home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume8 / jove / part03 < prev    next >
Encoding:
Internet Message Format  |  1987-02-02  |  57.8 KB

  1. Subject:  v08i022:  The JOVE text editor, Part03/13
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: seismo!rochester!jpayne (Jonathan Payne)
  6. Mod.sources: Volume 8, Issue 22
  7. Archive-name: jove/Part03
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. # If all goes well, you will see the message "End of archive 3 (of 13)."
  13. # Contents:  extend.c fp.c funcdefs.c insert.c table.c
  14. PATH=/bin:/usr/bin:/usr/ucb; export PATH
  15. echo shar: extracting "'extend.c'" '(17969 characters)'
  16. if test -f 'extend.c' ; then 
  17.   echo shar: will not over-write existing file "'extend.c'"
  18. else
  19. sed 's/^X//' >extend.c <<'@//E*O*F extend.c//'
  20. X/************************************************************************
  21. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  22. X * provided to you without charge, and with no warranty.  You may give  *
  23. X * away copies of JOVE, including sources, provided that this notice is *
  24. X * included in all the files.                                           *
  25. X ************************************************************************/
  26. X
  27. X#include "jove.h"
  28. X#include "io.h"
  29. X#include "termcap.h"
  30. X#include "ctype.h"
  31. X#ifdef JOB_CONTROL
  32. X#    include <signal.h>
  33. X#endif
  34. X
  35. X#include <varargs.h>
  36. X
  37. Xint    InJoverc = 0;
  38. X
  39. Xextern int    getch(),
  40. X        getchar();
  41. X
  42. X/* Auto execute code */
  43. X
  44. X#define NEXECS    20
  45. X
  46. Xprivate struct {
  47. X    char    *a_pattern;
  48. X    data_obj    *a_cmd;
  49. X} AutoExecs[NEXECS] = {0};
  50. X
  51. Xprivate int    ExecIndex = 0;
  52. X
  53. X/* Command auto-execute. */
  54. X
  55. XCAutoExec()
  56. X{
  57. X    DefAutoExec(findcom);
  58. X}
  59. X
  60. X/* Macro auto-execute. */
  61. X
  62. XMAutoExec()
  63. X{
  64. X    DefAutoExec(findmac);
  65. X}
  66. X
  67. X/* VARARGS0 */
  68. X
  69. XDefAutoExec(proc)
  70. Xdata_obj    *(*proc)();
  71. X{
  72. X    data_obj    *d;
  73. X    char    *pattern;
  74. X    int    i;
  75. X
  76. X    if (ExecIndex >= NEXECS)
  77. X        complain("Too many auto-executes, max %d.", NEXECS);
  78. X    if ((d = (*proc)(ProcFmt)) == 0)
  79. X        return;
  80. X    pattern = ask((char *) 0, ": %f %s ", d->Name);
  81. X    for (i = 0; i < ExecIndex; i++)
  82. X        if ((AutoExecs[i].a_cmd == d) &&
  83. X            (strcmp(pattern, AutoExecs[i].a_pattern) == 0))
  84. X                return;        /* Eliminate duplicates. */
  85. X    AutoExecs[ExecIndex].a_pattern = copystr(pattern);
  86. X    AutoExecs[ExecIndex].a_cmd = d;
  87. X    ExecIndex++;
  88. X}
  89. X
  90. X/* DoAutoExec: NEW and OLD are file names, and if NEW and OLD aren't the
  91. X   same kind of file (i.e., match the same pattern) or OLD is 0 and it
  92. X   matches, we execute the command associated with that kind of file. */
  93. XDoAutoExec(new, old)
  94. Xregister char    *new,
  95. X        *old;
  96. X{
  97. X    register int    i;
  98. X
  99. X    exp_p = YES;
  100. X    exp = 1;    /* So minor modes don't toggle.  We always want
  101. X               them on. */
  102. X    if (new == 0)
  103. X        return;
  104. X    for (i = 0; i < ExecIndex; i++)
  105. X        if ((LookingAt(AutoExecs[i].a_pattern, new, 0)) &&
  106. X            (old == 0 || !LookingAt(AutoExecs[i].a_pattern, old, 0)))
  107. X            ExecCmd(AutoExecs[i].a_cmd);
  108. X}
  109. X
  110. XBindAKey()
  111. X{
  112. X    BindSomething(findcom);
  113. X}
  114. X
  115. XBindMac()
  116. X{
  117. X    BindSomething(findmac);
  118. X}
  119. X
  120. Xextern int    EscPrefix(),
  121. X        CtlxPrefix(),
  122. X        MiscPrefix();
  123. X
  124. Xdata_obj **
  125. XIsPrefix(cp)
  126. Xdata_obj    *cp;
  127. X{
  128. X    int    (*proc)();
  129. X
  130. X    if (cp == 0 || (cp->Type & TYPEMASK) != FUNCTION)
  131. X        return 0;
  132. X    proc = ((struct cmd *) cp)->c_proc;
  133. X    if (proc == EscPrefix)
  134. X        return pref1map;
  135. X    if (proc == CtlxPrefix)
  136. X        return pref2map;
  137. X    if (proc == MiscPrefix)
  138. X        return miscmap;
  139. X    return 0;
  140. X}
  141. X
  142. Xunbind_aux(c)
  143. X{
  144. X    if (c == CR || c == LF)
  145. X        return FALSE;    /* tells do_ask to return */
  146. X    Insert(c);
  147. X    return !FALSE;
  148. X}
  149. X
  150. XUnbindC()
  151. X{
  152. X    char    *keys;
  153. X    data_obj    **map = mainmap;
  154. X
  155. X    keys = do_ask("\r\n\01\02\03\04\05\06\010\011\013\014\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037", unbind_aux, (char *) 0, ProcFmt);
  156. X    if (keys == 0)
  157. X        return;
  158. X    for (;;) {
  159. X        if (keys[1] == '\0')
  160. X            break;
  161. X        if ((map = IsPrefix(map[*keys])) == 0)
  162. X            break;
  163. X        keys++;
  164. X    }
  165. X    if (keys[1] != 0)
  166. X        complain("That's not a legitimate key sequence.");
  167. X    map[keys[0]] = 0;
  168. X}
  169. X        
  170. Xaddgetc()
  171. X{
  172. X    int    c;
  173. X
  174. X    if (!InJoverc)
  175. X        Asking = strlen(mesgbuf);
  176. X    c = getch();
  177. X    if (InJoverc) {
  178. X        if (c == '\n')
  179. X            return EOF;    /* this isn't part of the sequence */
  180. X        else if (c == '\\') {
  181. X            if ((c = getch()) == LF)
  182. X                complain("[Premature end of line]");
  183. X        } else if (c == '^') {
  184. X            if ((c = getch()) == '?')
  185. X                c = RUBOUT;
  186. X            else if (isalpha(c) || index("[\\]^_", c))
  187. X                c = c - '@';
  188. X            else
  189. X                complain("[Unknown control character]");
  190. X        }
  191. X    }
  192. X
  193. X    Asking = 0;
  194. X    add_mess("%p ", c);
  195. X
  196. X    return c;
  197. X}
  198. X
  199. XBindWMap(map, lastkey, cmd)
  200. Xdata_obj    **map,
  201. X        *cmd;
  202. X{
  203. X    data_obj    **nextmap;
  204. X    int    c;
  205. X
  206. X    c = addgetc();
  207. X    if (c == EOF) {
  208. X        if (lastkey == EOF)
  209. X            complain("[Empty key sequence]");
  210. X        complain("[Premature end of key sequence]");
  211. X    } else {
  212. X        if (nextmap = IsPrefix(map[c]))
  213. X            BindWMap(nextmap, c, cmd);
  214. X        else
  215. X            map[c] = cmd;
  216. X    }
  217. X}
  218. X
  219. X/* VARARGS0 */
  220. X
  221. XBindSomething(proc)
  222. Xdata_obj    *(*proc)();
  223. X{
  224. X    data_obj    *d;
  225. X
  226. X    if ((d = (*proc)(ProcFmt)) == 0)
  227. X        return;
  228. X    s_mess(": %f %s ", d->Name);
  229. X    BindWMap(mainmap, EOF, d);
  230. X}
  231. X
  232. X/* Describe key */
  233. X
  234. XDescWMap(map, key)
  235. Xdata_obj    **map;
  236. X{
  237. X    data_obj    *cp = map[key],
  238. X            **prefp;
  239. X
  240. X    if (cp == 0)
  241. X        add_mess("is unbound.");
  242. X    else if (prefp = IsPrefix(cp))
  243. X        DescWMap(prefp, addgetc());
  244. X    else
  245. X        add_mess("is bound to %s.", cp->Name);
  246. X}
  247. X
  248. XKeyDesc()
  249. X{
  250. X    s_mess(ProcFmt);
  251. X    DescWMap(mainmap, addgetc());
  252. X}
  253. X
  254. XDescCom()
  255. X{
  256. X    data_obj    *dp;
  257. X    char    pattern[100],
  258. X        doc_type[40],
  259. X        *file = CmdDb;
  260. X    File    *fp;
  261. X
  262. X    if (!strcmp(LastCmd->Name, "describe-variable"))
  263. X        dp = (data_obj *) findvar(ProcFmt);
  264. X    else
  265. X        dp = (data_obj *) findcom(ProcFmt);
  266. X
  267. X    if (dp == 0)
  268. X        return;
  269. X    fp = open_file(file, iobuff, F_READ, COMPLAIN, QUIET);
  270. X    Placur(ILI, 0);
  271. X    flusho();
  272. X    sprintf(pattern, "^:entry \"%s\" \"\\([^\"]*\\)\"", dp->Name);
  273. X    TOstart("Help", TRUE);
  274. X    for (;;) {
  275. X        if (f_gets(fp, genbuf, LBSIZE) == EOF) {
  276. X            Typeout("There is no documentation for \"%s\".", dp->Name);
  277. X            goto outahere;
  278. X        }
  279. X        if ((strncmp(genbuf, ":entry", 6) == 0) && LookingAt(pattern, genbuf, 0))
  280. X            break;
  281. X    }
  282. X    /* found it ... let's print it */
  283. X    putmatch(1, doc_type, sizeof doc_type);
  284. X    if (strcmp("Variable", doc_type) == 0)
  285. X        Typeout(dp->Name);
  286. X    else if (strcmp("Command", doc_type) == 0) {
  287. X        char    binding[128];
  288. X
  289. X        find_binds(dp, binding);
  290. X        if (blnkp(binding))
  291. X            Typeout("To invoke %s, type \"ESC X %s<cr>\".",
  292. X                dp->Name,
  293. X                dp->Name);
  294. X        else
  295. X            Typeout("Type \"%s\" to invoke %s.", binding, dp->Name);
  296. X    }
  297. X    Typeout("");
  298. X    while (f_gets(fp, genbuf, LBSIZE) != EOF)
  299. X        if (strncmp(genbuf, ":entry", 6) == 0)
  300. X            goto outahere;
  301. X        else
  302. X            Typeout("%s", genbuf);
  303. Xoutahere:
  304. X    f_close(fp);
  305. X    TOstop();
  306. X}
  307. X
  308. XDescBindings()
  309. X{
  310. X    extern int    Typeout();
  311. X
  312. X    TOstart("Key Bindings", TRUE);
  313. X    DescMap(mainmap, NullStr);
  314. X    TOstop();
  315. X}
  316. X
  317. XDescMap(map, pref)
  318. Xdata_obj    **map;
  319. Xchar    *pref;
  320. X{
  321. X    int    c1,
  322. X        c2 = 0,
  323. X        numbetween;
  324. X    char    keydescbuf[40];
  325. X    data_obj    **prefp;
  326. X
  327. X    for (c1 = 0; c1 < 0200 && c2 < 0200; c1 = c2 + 1) {
  328. X        c2 = c1;
  329. X        if (map[c1] == 0)
  330. X            continue;
  331. X        while (++c2 < 0200 && map[c1] == map[c2])
  332. X            ;
  333. X        c2--;
  334. X        numbetween = c2 - c1;
  335. X        if (numbetween == 1)
  336. X            sprintf(keydescbuf, "%s {%p,%p}", pref, c1, c2);
  337. X        else if (numbetween == 0)
  338. X            sprintf(keydescbuf, "%s %p", pref, c1);
  339. X        else
  340. X            sprintf(keydescbuf, "%s [%p-%p]", pref, c1, c2);
  341. X        if (prefp = IsPrefix(map[c1]))
  342. X            DescMap(prefp, keydescbuf);
  343. X        else
  344. X            Typeout("%-14s%s", keydescbuf, map[c1]->Name);
  345. X    }
  346. X}
  347. X
  348. Xprivate
  349. Xfind_binds(dp, buf)
  350. Xdata_obj    *dp;
  351. Xchar    *buf;
  352. X{
  353. X    char    *endp;
  354. X
  355. X    buf[0] = '\0';
  356. X    fb_aux(dp, mainmap, (char *) 0, buf);
  357. X    endp = buf + strlen(buf) - 2;
  358. X    if ((endp > buf) && (strcmp(endp, ", ") == 0))
  359. X        *endp = '\0';
  360. X}
  361. X
  362. Xprivate
  363. Xfb_aux(cp, map, prefix, buf)
  364. Xregister data_obj    *cp,
  365. X            **map;
  366. Xchar    *buf,
  367. X    *prefix;
  368. X{
  369. X    int    c1,
  370. X        c2;
  371. X    char    *bufp = buf + strlen(buf),
  372. X        prefbuf[20];
  373. X    data_obj    **prefp;
  374. X
  375. X    for (c1 = c2 = 0; c1 < 0200 && c2 < 0200; c1 = c2 + 1) {
  376. X        c2 = c1;
  377. X        if (map[c1] == cp) {
  378. X            while (++c2 < 0200 && map[c1] == map[c2])
  379. X                ;
  380. X            c2--;
  381. X            if (prefix)
  382. X                sprintf(bufp, "%s ", prefix);
  383. X            bufp += strlen(bufp);
  384. X            switch (c2 - c1) {
  385. X            case 0:
  386. X                sprintf(bufp, "%p, ", c1);
  387. X                break;
  388. X    
  389. X            case 1:
  390. X                sprintf(bufp, "{%p,%p}, ", c1, c2);
  391. X                break;
  392. X    
  393. X            default:
  394. X                sprintf(bufp, "[%p-%p], ", c1, c2);
  395. X                break;
  396. X            }
  397. X        }
  398. X        if (prefp = IsPrefix(map[c1])) {
  399. X            sprintf(prefbuf, "%p", c1);
  400. X            fb_aux(cp, prefp, prefbuf, bufp);
  401. X        }
  402. X        bufp += strlen(bufp);
  403. X    }
  404. X}
  405. X
  406. XApropos()
  407. X{
  408. X    register struct cmd    *cp;
  409. X    register struct macro    *m;
  410. X    register struct variable    *v;
  411. X    char    *ans;
  412. X    int    anyfs = 0,
  413. X        anyvs = 0,
  414. X        anyms = 0;
  415. X    char    buf[256];
  416. X
  417. X    ans = ask((char *) 0, ": %f (keyword) ");
  418. X    TOstart("Help", TRUE);
  419. X    for (cp = commands; cp->Name != 0; cp++)
  420. X        if (sindex(ans, cp->Name)) {
  421. X            if (anyfs == 0) {
  422. X                Typeout("Commands");
  423. X                Typeout("--------");
  424. X            }
  425. X            find_binds((data_obj *) cp, buf);
  426. X            if (buf[0])
  427. X                Typeout(": %-35s(%s)", cp->Name, buf);
  428. X            else
  429. X                Typeout(": %s", cp->Name);
  430. X            anyfs++;
  431. X        }
  432. X    if (anyfs)
  433. X        Typeout(NullStr);
  434. X    for (v = variables; v->Name != 0; v++)
  435. X        if (sindex(ans, v->Name)) {
  436. X            if (anyvs == 0) {
  437. X                Typeout("Variables");
  438. X                Typeout("---------");
  439. X            }
  440. X            anyvs++;
  441. X            vpr_aux(v, buf);
  442. X            Typeout(": set %-26s%s", v->Name, buf);
  443. X        }
  444. X    if (anyvs)
  445. X        Typeout(NullStr);
  446. X    for (m = macros; m != 0; m = m->m_nextm)
  447. X        if (sindex(ans, m->Name)) {
  448. X            if (anyms == 0) {
  449. X                Typeout("Macros");
  450. X                Typeout("------");
  451. X            }
  452. X            anyms++;
  453. X            find_binds((data_obj *) m, buf);
  454. X            if (buf[0])
  455. X                Typeout(": %-35s(%s)", m->Name, buf);
  456. X            else
  457. X                Typeout(": %-35s%s", "execute-macro", m->Name);
  458. X        }
  459. X    TOstop();
  460. X}
  461. X
  462. XExtend()
  463. X{
  464. X    data_obj    *d;
  465. X
  466. X    if (d = findcom(": "))
  467. X        ExecCmd(d);
  468. X}
  469. X
  470. X/* Read a positive integer from CP.  It must be in base BASE, and
  471. X   complains if it isn't.  If allints is nonzero, all the characters
  472. X   in the string must be integers or we return -1; otherwise we stop
  473. X   reading at the first nondigit. */
  474. X
  475. Xchr_to_int(cp, base, allints)
  476. Xregister char    *cp;
  477. X{
  478. X    register int    c;
  479. X    int    value = 0;
  480. X
  481. X    while (c = *cp++) {
  482. X        if (!isdigit(c)) {
  483. X            if (allints)
  484. X                return -1;
  485. X            break;
  486. X        }
  487. X        c = c - '0';
  488. X        if (c >= base)
  489. X            complain("You must specify in base %d.", base);
  490. X        value = value * base + c;
  491. X    }
  492. X    return value;
  493. X}
  494. X
  495. Xask_int(prompt, base)
  496. Xchar    *prompt;
  497. Xint    base;
  498. X{
  499. X    char    *val = ask((char *) 0, prompt);
  500. X    int    value = chr_to_int(val, base, 1);
  501. X
  502. X    if (value < 0)
  503. X        complain("That's not a number!");
  504. X    return value;
  505. X}
  506. X
  507. Xprivate
  508. Xvpr_aux(vp, buf)
  509. Xregister struct variable    *vp;
  510. Xchar    *buf;
  511. X{
  512. X    switch (vp->v_flags & V_TYPEMASK) {
  513. X    case V_BASE10:
  514. X        sprintf(buf, "%d", *(vp->v_value));
  515. X        break;
  516. X
  517. X    case V_BASE8:
  518. X        sprintf(buf, "%o", *(vp->v_value));
  519. X        break;
  520. X
  521. X    case V_BOOL:
  522. X        sprintf(buf, (*(vp->v_value)) ? "on" : "off");
  523. X        break;
  524. X
  525. X    case V_STRING:
  526. X    case V_FILENAME:
  527. X        sprintf(buf, "%s", (char *) vp->v_value);
  528. X        break;
  529. X
  530. X    case V_CHAR:
  531. X        sprintf(buf, "%p", *(vp->v_value));
  532. X        break;
  533. X    }
  534. X}
  535. X
  536. XPrVar()
  537. X{
  538. X    struct variable    *vp;
  539. X    char    prbuf[256];
  540. X
  541. X    if ((vp = (struct variable *) findvar(ProcFmt)) == 0)
  542. X        return;
  543. X    vpr_aux(vp, prbuf);
  544. X    s_mess(": %f %s => %s", vp->Name, prbuf);
  545. X}
  546. X
  547. XSetVar()
  548. X{
  549. X    struct variable    *vp;
  550. X    char    *prompt;
  551. X
  552. X    if ((vp = (struct variable *) findvar(ProcFmt)) == 0)
  553. X        return;
  554. X    prompt = sprint(": %f %s ", vp->Name);
  555. X
  556. X    switch (vp->v_flags & V_TYPEMASK) {
  557. X    case V_BASE10:
  558. X    case V_BASE8:
  559. X        {
  560. X            int    value;
  561. X
  562. X        value = ask_int(prompt, ((vp->v_flags & V_TYPEMASK) == V_BASE10)
  563. X                      ? 10 : 8);
  564. X        *(vp->v_value) = value;
  565. X            break;
  566. X        }
  567. X
  568. X    case V_BOOL:
  569. X        {
  570. X            char    *def = *(vp->v_value) ? "off" : "on",
  571. X                *on_off;
  572. X            int    value;
  573. X
  574. X            on_off = ask(def, prompt);
  575. X        if (casecmp(on_off, "on") == 0)
  576. X            value = ON;
  577. X            else if (casecmp(on_off, "off") == 0)
  578. X                value = OFF;
  579. X            else
  580. X                complain("Boolean variables must be ON or OFF.");
  581. X            *(vp->v_value) = value;
  582. X            s_mess("%s%s", prompt, value ? "on" : "off");
  583. X            break;
  584. X        }
  585. X
  586. X    case V_FILENAME:
  587. X        {
  588. X        char    fbuf[FILESIZE];
  589. X
  590. X            sprintf(&prompt[strlen(prompt)], "(default %s) ", vp->v_value);
  591. X            (void) ask_file(prompt, (char *) vp->v_value, fbuf);
  592. X        strcpy((char *) vp->v_value, fbuf);
  593. X            break;
  594. X        }
  595. X
  596. X    case V_STRING:
  597. X        {
  598. X        char    *str;
  599. X
  600. X            /* Do_ask() so you can set string to "" if you so desire. */
  601. X            str = do_ask("\r\n", (int (*)()) 0, (char *) vp->v_value, prompt);
  602. X            if (str == 0)
  603. X            str = NullStr;
  604. X            strcpy((char *) vp->v_value, str);
  605. X        /* ... and hope there is enough room. */
  606. X            break;
  607. X        }
  608. X    case V_CHAR:
  609. X        f_mess(prompt);
  610. X            *(vp->v_value) = addgetc();
  611. X        break;            
  612. X
  613. X    }
  614. X    if (vp->v_flags & V_MODELINE)
  615. X        UpdModLine++;
  616. X    if (vp->v_flags & V_CLRSCREEN)
  617. X        ClAndRedraw();
  618. X    if (vp->v_flags & V_TTY_RESET)
  619. X        tty_reset();
  620. X}
  621. X            
  622. X/* Command completion - possible is an array of strings, prompt is
  623. X   the prompt to use, and flags are ... well read jove.h.
  624. X
  625. X   If flags are RET_STATE, and the user hits <return> what they typed
  626. X   so far is in the Minibuf string. */
  627. X
  628. Xprivate char    **Possible;
  629. Xprivate int    comp_value,
  630. X        comp_flags;
  631. X
  632. Xaux_complete(c)
  633. X{
  634. X    int    command,
  635. X        length,
  636. X        i;
  637. X
  638. X    if (comp_flags & CASEIND) {
  639. X        char    *lp;
  640. X
  641. X        for (lp = linebuf; *lp != '\0'; lp++)
  642. X            if (isupper(*lp))
  643. X                *lp = tolower(*lp);
  644. X    }
  645. X    switch (c) {
  646. X    case EOF:
  647. X        comp_value = -1;
  648. X        return 0;
  649. X
  650. X    case '\r':
  651. X    case '\n':
  652. X        command = match(Possible, linebuf);
  653. X        if (command >= 0) {
  654. X            comp_value = command;
  655. X            return 0;    /* tells ask to stop */
  656. X        }
  657. X        if (eolp() && bolp()) {
  658. X            comp_value = NULLSTRING;
  659. X            return 0;
  660. X        }
  661. X        if (comp_flags & RET_STATE) switch (command) {
  662. X            case UNIQUE:
  663. X            case ORIGINAL:
  664. X            case NULLSTRING:
  665. X                comp_value = command;
  666. X                return 0;
  667. X
  668. X            default:
  669. X                break;
  670. X        }
  671. X        if (InJoverc)
  672. X            complain("[\"%s\" unknown]", linebuf);
  673. X        rbell();
  674. X        break;
  675. X
  676. X    case '\t':
  677. X    case ' ':
  678. X        {
  679. X        int    minmatch = 1000,
  680. X                maxmatch = 0,
  681. X                numfound = 0,
  682. X                lastmatch = -1,
  683. X            length = strlen(linebuf);
  684. X
  685. X        for (i = 0; Possible[i] != 0; i++) {
  686. X            int    this_len;
  687. X
  688. X            this_len = numcomp(Possible[i], linebuf);
  689. X            maxmatch = max(maxmatch, this_len);
  690. X            if (this_len >= length) {
  691. X                if (numfound)
  692. X                    minmatch = min(minmatch, numcomp(Possible[lastmatch], Possible[i]));
  693. X                else
  694. X                    minmatch = strlen(Possible[i]);
  695. X                numfound++;
  696. X                lastmatch = i;
  697. X                if (strcmp(linebuf, Possible[i]) == 0)
  698. X                    break;
  699. X            }
  700. X        }
  701. X
  702. X        if (numfound == 0) {
  703. X            rbell();
  704. X            if (InJoverc)
  705. X                complain("[\"%s\" unknown]", linebuf);
  706. X            /* If we're not in the .joverc then
  707. X               let's do something helpful for the
  708. X               user. */
  709. X            if (maxmatch < length) {
  710. X                char    *cp;
  711. X
  712. X                cp = linebuf + maxmatch;
  713. X                *cp = 0;
  714. X                Eol();
  715. X            }
  716. X            break;
  717. X        }
  718. X            if (c != '\t' && numfound == 1) {
  719. X                comp_value = lastmatch;
  720. X            return 0;
  721. X        }
  722. X        null_ncpy(linebuf, Possible[lastmatch], minmatch);
  723. X            Eol();
  724. X        if (minmatch == length)    /* No difference */
  725. X            rbell();
  726. X        break;
  727. X        }
  728. X
  729. X    case '?':
  730. X        if (InJoverc)
  731. X            complain((char *) 0);
  732. X        /* kludge: in case we're using UseBuffers, in which case
  733. X           linebuf gets written all over */
  734. X        strcpy(Minibuf, linebuf);
  735. X        length = strlen(Minibuf);
  736. X        TOstart("Completion", TRUE);    /* for now ... */
  737. X        for (i = 0; Possible[i]; i++)
  738. X            if (numcomp(Possible[i], Minibuf) >= length) {
  739. X                Typeout(Possible[i]);
  740. X                if (TOabort != 0)
  741. X                    break;
  742. X            }
  743. X
  744. X        TOstop();
  745. X        break;
  746. X    }
  747. X    return !FALSE;
  748. X}
  749. X
  750. Xcomplete(possible, prompt, flags)
  751. Xregister char    *possible[];
  752. Xchar    *prompt;
  753. X{
  754. X    Possible = possible;
  755. X    comp_flags = flags;
  756. X    (void) do_ask("\r\n \t?", aux_complete, NullStr, prompt);
  757. X    return comp_value;
  758. X}
  759. X
  760. Xmatch(choices, what)
  761. Xregister char    **choices,
  762. X        *what;
  763. X{
  764. X    register int    len;
  765. X    int    i,
  766. X        found = 0,
  767. X        save,
  768. X        exactmatch = -1;
  769. X
  770. X    len = strlen(what);
  771. X    if (len == 0)
  772. X        return NULLSTRING;
  773. X    for (i = 0; choices[i]; i++) {
  774. X        if (strncmp(what, choices[i], len) == 0) {
  775. X            if (strcmp(what, choices[i]) == 0)
  776. X                exactmatch = i;
  777. X            save = i;
  778. X            found++;    /* Found one. */
  779. X        }
  780. X    }
  781. X
  782. X    if (found == 0)
  783. X        save = ORIGINAL;
  784. X    else if (found > 1) {
  785. X        if (exactmatch != -1)
  786. X            save = exactmatch;
  787. X        else
  788. X            save = AMBIGUOUS;
  789. X    }
  790. X
  791. X    return save;
  792. X}
  793. X
  794. XSource()
  795. X{
  796. X    char    *com,
  797. X        buf[FILESIZE];
  798. X
  799. X    sprintf(buf, "%s/.joverc", getenv("HOME"));
  800. X    com = ask_file((char *) 0, buf, buf);
  801. X    if (joverc(buf) == NIL)
  802. X        complain(IOerr("read", com));
  803. X}
  804. X
  805. XBufPos()
  806. X{
  807. X    register Line    *lp = curbuf->b_first;
  808. X    register int    i,
  809. X            dotline;
  810. X    long    dotchar,
  811. X        nchars;
  812. X
  813. X    for (i = nchars = 0; lp != 0; i++, lp = lp->l_next) {
  814. X        if (lp == curline) {
  815. X            dotchar = nchars + curchar;
  816. X            dotline = i + 1;
  817. X        }
  818. X        nchars += length(lp) + (lp->l_next != 0); /* include the NL */
  819. X    }
  820. X
  821. X    s_mess("[\"%s\" line %d of %d, char %D of %D (%d%%)]",
  822. X            filename(curbuf),
  823. X            dotline,
  824. X            i,
  825. X            dotchar,
  826. X            nchars,
  827. X            (int) (((long) dotchar * 100) / nchars));
  828. X}
  829. X
  830. X#define IF_UNBOUND    -1
  831. X#define IF_TRUE        1
  832. X#define IF_FALSE    !IF_TRUE
  833. X
  834. Xdo_if(cmd)
  835. Xchar    *cmd;
  836. X{
  837. X    int    pid,
  838. X        status;
  839. X
  840. X    switch (pid = fork()) {
  841. X    case -1:
  842. X        complain("[Fork failed: if]");
  843. X
  844. X    case 0:
  845. X        {
  846. X        char    *args[12],
  847. X            *cp = cmd,
  848. X            **ap = args;
  849. X
  850. X            *ap++ = cmd;
  851. X            for (;;) {
  852. X            if ((cp = index(cp, ' ')) == 0)
  853. X                break;
  854. X            *cp++ = '\0';
  855. X            *ap++ = cp;
  856. X        }
  857. X        *ap = 0;
  858. X
  859. X        close(0);    /*    we want reads to fail */
  860. X        /* close(1);     but not writes or ioctl's
  861. X        close(2);    */
  862. X
  863. X            (void) execvp(args[0], args);
  864. X        _exit(-10);    /* signals exec error (see below) */
  865. X        }
  866. X    }
  867. X#ifdef IPROCS
  868. X    sighold(SIGCHLD);
  869. X#endif
  870. X    dowait(pid, &status);
  871. X#ifdef IPROCS
  872. X    sigrelse(SIGCHLD);
  873. X#endif
  874. X    if (status == -10)
  875. X        complain("[Exec failed]");
  876. X    if (status < 0)
  877. X        complain("[Exit %d]", status);
  878. X    return (status == 0);    /* 0 means successful */
  879. X}
  880. X
  881. Xjoverc(file)
  882. Xchar    *file;
  883. X{
  884. X    char    buf[LBSIZE],
  885. X        lbuf[128];
  886. X    int    lnum = 0,
  887. X        eof = FALSE;
  888. X    jmp_buf    savejmp;
  889. X    int    IfStatus = IF_UNBOUND;
  890. X    File    *fp;
  891. X
  892. X    fp = open_file(file, buf, F_READ, !COMPLAIN, QUIET);
  893. X    if (fp == NIL)
  894. X        return NIL;
  895. X
  896. X    /* Catch any errors, here, and do the right thing with them,
  897. X       and then restore the error handle to whoever did a setjmp
  898. X       last. */
  899. X
  900. X    push_env(savejmp);
  901. X    if (setjmp(mainjmp)) {
  902. X        Buffer    *savebuf = curbuf;
  903. X
  904. X        SetBuf(do_select((Window *) 0, "RC errors"));
  905. X        ins_str(sprint("%s:%d:%s\t%s\n", pr_name(file), lnum, lbuf, mesgbuf), NO);
  906. X        unmodify();
  907. X        SetBuf(savebuf);
  908. X        Asking = 0;
  909. X    }
  910. X    InJoverc = 1;
  911. X    if (!eof) do {
  912. X        eof = (f_gets(fp, lbuf, sizeof lbuf) == EOF);
  913. X        lnum++;
  914. X        if (casencmp(lbuf, "if", 2) == 0) {
  915. X            char    cmd[128];
  916. X
  917. X            if (IfStatus != IF_UNBOUND)
  918. X                complain("[Cannot have nested if's]");
  919. X            if (LookingAt("if[ \t]*\\(.*\\)$", lbuf, 0) == 0)
  920. X                complain("[If syntax error]");
  921. X            putmatch(1, cmd, sizeof cmd);
  922. X            IfStatus = do_if(cmd) ? IF_TRUE : IF_FALSE;
  923. X            continue;
  924. X        } else if (casencmp(lbuf, "else", 4) == 0) {
  925. X            if (IfStatus == IF_UNBOUND)
  926. X                complain("[Unexpected `else']");
  927. X            IfStatus = !IfStatus;
  928. X            continue;
  929. X        } else if (casencmp(lbuf, "endif", 5) == 0) {
  930. X            if (IfStatus == IF_UNBOUND)
  931. X                complain("[Unexpected `endif']");
  932. X            IfStatus = IF_UNBOUND;
  933. X            continue;
  934. X        }
  935. X        if (IfStatus == IF_FALSE)
  936. X            continue;
  937. X        (void) strcat(lbuf, "\n");
  938. X        Inputp = lbuf;
  939. X        while (*Inputp == ' ' || *Inputp == '\t')
  940. X            Inputp++;    /* skip white space */
  941. X        Extend();
  942. X    } while (!eof);
  943. X
  944. X    f_close(fp);
  945. X    pop_env(savejmp);
  946. X    Inputp = 0;
  947. X    Asking = 0;
  948. X    InJoverc = 0;
  949. X    if (IfStatus != IF_UNBOUND)
  950. X        complain("[Missing endif]");
  951. X    return !NIL;
  952. X}
  953. @//E*O*F extend.c//
  954. if test 17969 -ne "`wc -c <'extend.c'`"; then
  955.     echo shar: error transmitting "'extend.c'" '(should have been 17969 characters)'
  956. fi
  957. fi # end of overwriting check
  958. echo shar: extracting "'fp.c'" '(5151 characters)'
  959. if test -f 'fp.c' ; then 
  960.   echo shar: will not over-write existing file "'fp.c'"
  961. else
  962. sed 's/^X//' >fp.c <<'@//E*O*F fp.c//'
  963. X/************************************************************************
  964. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  965. X * provided to you without charge, and with no warranty.  You may give  *
  966. X * away copies of JOVE, including sources, provided that this notice is *
  967. X * included in all the files.                                           *
  968. X ************************************************************************/
  969. X
  970. X#include "jove.h"
  971. X#include "io.h"
  972. X#include "termcap.h"
  973. X#include <sys/stat.h>
  974. X#include <sys/file.h>
  975. X#include <errno.h>
  976. X
  977. X#define MAXFILES    20    /* good enough for my purposes */
  978. X
  979. Xstatic File    _openfiles[MAXFILES] = {0};
  980. X
  981. Xstatic File *
  982. Xf_alloc(name, flags, fd, buffer, buf_size)
  983. Xchar    *name,
  984. X    *buffer;
  985. X{
  986. X    register File    *fp;
  987. X    register int    i;
  988. X
  989. X    for (fp = _openfiles, i = 0; i < MAXFILES; i++, fp++)
  990. X        if (fp->f_flags == 0)
  991. X            break;
  992. X    if (i == MAXFILES)
  993. X        complain("[Too many open files!]");
  994. X    fp->f_bufsize = buf_size;
  995. X    fp->f_cnt = 0;
  996. X    fp->f_fd = fd;
  997. X    fp->f_flags = flags;
  998. X    if (buffer == 0) {
  999. X        buffer = emalloc(buf_size);
  1000. X        fp->f_flags |= F_MYBUF;
  1001. X    }
  1002. X    fp->f_base = fp->f_ptr = buffer;
  1003. X    fp->f_name = copystr(name);
  1004. X
  1005. X    return fp;
  1006. X}
  1007. X
  1008. Xgc_openfiles()
  1009. X{
  1010. X    register File    *fp;
  1011. X
  1012. X    for (fp = _openfiles; fp < &_openfiles[MAXFILES]; fp++)
  1013. X        if (fp->f_flags != 0 && (fp->f_flags & F_LOCKED) == 0)
  1014. X            f_close(fp);
  1015. X}
  1016. X
  1017. XFile *
  1018. Xfd_open(name, flags, fd, buffer, bsize)
  1019. Xchar    *name,
  1020. X    *buffer;
  1021. X{
  1022. X    return f_alloc(name, flags, fd, buffer, bsize);
  1023. X}
  1024. X
  1025. XFile *
  1026. Xf_open(name, flags, buffer, buf_size)
  1027. Xchar    *name,
  1028. X    *buffer;
  1029. X{
  1030. X    register int    fd;
  1031. X    int    mode = F_MODE(flags);
  1032. X
  1033. X    if (mode == F_READ)
  1034. X        fd = open(name, 0);
  1035. X    if (mode == F_APPEND) {
  1036. X        fd = open(name, 1);
  1037. X        if (fd == -1)
  1038. X            mode = F_WRITE;
  1039. X        else
  1040. X            (void) lseek(fd, 0L, 2);
  1041. X    }
  1042. X    if (mode == F_WRITE)
  1043. X        fd = creat(name, CreatMode);
  1044. X    if (fd == -1)
  1045. X        return NIL;
  1046. X    return f_alloc(name, flags, fd, buffer, buf_size);
  1047. X}
  1048. X
  1049. Xf_close(fp)
  1050. XFile    *fp;
  1051. X{
  1052. X    flush(fp);
  1053. X#ifdef BSD4_2 
  1054. X    if (fp->f_flags & (F_WRITE|F_APPEND))
  1055. X        (void) fsync(fp->f_fd);
  1056. X#endif 
  1057. X    (void) close(fp->f_fd);
  1058. X    if (fp->f_flags & F_MYBUF)
  1059. X        free(fp->f_base);
  1060. X    free(fp->f_name);
  1061. X    fp->f_flags = 0;    /* indicates that we're available */
  1062. X}
  1063. X
  1064. Xfilbuf(fp)
  1065. XFile    *fp;
  1066. X{
  1067. X    if (fp->f_flags & (F_EOF|F_ERR))
  1068. X        return EOF;
  1069. X    fp->f_ptr = fp->f_base;
  1070. X    fp->f_cnt = read(fp->f_fd, fp->f_base, fp->f_bufsize);
  1071. X    if (fp->f_cnt == -1) {
  1072. X        printf("[Read error %d]", errno);
  1073. X        fp->f_flags |= F_ERR;
  1074. X    }
  1075. X    if (fp->f_cnt == 0) {
  1076. X        fp->f_flags |= F_EOF;
  1077. X        return EOF;
  1078. X    }
  1079. X    io_chars += fp->f_cnt;
  1080. X    return getc(fp);
  1081. X}
  1082. X
  1083. Xputstr(s)
  1084. Xregister char    *s;
  1085. X{
  1086. X    register int    c;
  1087. X
  1088. X    while (c = *s++)
  1089. X        putchar(c);
  1090. X}
  1091. X
  1092. Xfputnchar(s, n, fp)
  1093. Xregister char    *s;
  1094. Xregister int    n;
  1095. Xregister File    *fp;
  1096. X{
  1097. X    while (--n >= 0)
  1098. X        putc(*s++, fp);
  1099. X}
  1100. X
  1101. Xflusho()
  1102. X{
  1103. X    _flush(EOF, stdout);
  1104. X}
  1105. X
  1106. Xflush(fp)
  1107. XFile    *fp;
  1108. X{
  1109. X    _flush(EOF, fp);
  1110. X}
  1111. X
  1112. X_flush(c, fp)
  1113. Xregister File    *fp;
  1114. X{
  1115. X    register int    n;
  1116. X
  1117. X    if (fp->f_flags & (F_READ | F_STRING | F_ERR))
  1118. X        return;
  1119. X    if (((n = (fp->f_ptr - fp->f_base)) > 0) &&
  1120. X        (write(fp->f_fd, fp->f_base, n) != n) &&
  1121. X        (fp != stdout)) {
  1122. X            fp->f_flags |= F_ERR;
  1123. X        error("[I/O error(%d); file = %s, fd = %d]",
  1124. X            errno, fp->f_name, fp->f_fd);
  1125. X    }
  1126. X
  1127. X    if (fp == stdout)
  1128. X        OkayAbort = YES;
  1129. X    fp->f_cnt = fp->f_bufsize;
  1130. X    fp->f_ptr = fp->f_base;
  1131. X    if (c != EOF)
  1132. X        putc(c, fp);
  1133. X}
  1134. X
  1135. Xf_gets(fp, buf, max)
  1136. Xregister File    *fp;
  1137. Xchar    *buf;
  1138. X{
  1139. X    register char    *cp = buf;
  1140. X    register int    c;
  1141. X    char    *endp = buf + max - 1;
  1142. X
  1143. X    if (fp->f_flags & F_EOF)
  1144. X        return EOF;
  1145. X    while (((c = getc(fp)) != EOF) && (c != '\n')) {
  1146. X        if (c == NULL)
  1147. X            continue;    /* sorry we don't read nulls */
  1148. X        if (cp >= endp) {
  1149. X            add_mess(" [Line too long]");
  1150. X            rbell();
  1151. X            return EOF;
  1152. X        }
  1153. X        *cp++ = c;
  1154. X    }
  1155. X    *cp = '\0';
  1156. X    if (c == EOF) {
  1157. X        if (cp != buf)
  1158. X            add_mess(" [Incomplete last line]");
  1159. X        fp->f_flags |= F_EOF;
  1160. X        return EOF;
  1161. X    }
  1162. X    io_lines++;
  1163. X    return NIL;    /* this means okay */
  1164. X}
  1165. X
  1166. X/* Deals with output to the terminal, setting up the amount of characters
  1167. X   to be buffered depending on the output baud rate.  Why it's in a 
  1168. X   separate file I don't know ... */
  1169. X
  1170. Xstatic char    one_buf;
  1171. X
  1172. Xint    BufSize = 1;
  1173. X
  1174. Xstatic File    _stdout = {1, 1, 1, F_WRITE, &one_buf, &one_buf};
  1175. XFile    *stdout = &_stdout;
  1176. X
  1177. X/* put a string with padding */
  1178. X
  1179. Xtputc(c)
  1180. X{
  1181. X    putchar(c);
  1182. X}
  1183. X
  1184. X#undef putchar        /* for files which forget to include io.h,
  1185. X               here's a real putchar procedure. */
  1186. Xputchar(c)
  1187. X{
  1188. X    putc(c, stdout);
  1189. X}
  1190. X
  1191. Xputpad(str, lines)
  1192. Xchar    *str;
  1193. X{
  1194. X    if (str)
  1195. X        tputs(str, lines, tputc);
  1196. X}
  1197. X
  1198. X/* Determine the number of characters to buffer at each baud rate.  The
  1199. X   lower the number, the quicker the response when new input arrives.  Of
  1200. X   course the lower the number, the more prone the program is to stop in
  1201. X   output.  Decide what matters most to you. This sets BufSize to the right
  1202. X   number or chars, and initiaizes `stdout'.  */
  1203. X
  1204. Xsettout(ttbuf)
  1205. Xchar    *ttbuf;
  1206. X{
  1207. X    static int speeds[] = {
  1208. X        1,    /* 0    */
  1209. X        1,    /* 50    */
  1210. X        1,    /* 75    */
  1211. X        1,    /* 110    */
  1212. X        1,    /* 134    */
  1213. X        1,    /* 150    */
  1214. X        1,    /* 200    */
  1215. X        2,    /* 300    */
  1216. X        4,    /* 600    */
  1217. X        8,    /* 1200 */
  1218. X        16,    /* 1800    */
  1219. X        32,    /* 2400    */
  1220. X        128,    /* 4800    */
  1221. X        256,    /* 9600    */
  1222. X        512,    /* EXTA    */
  1223. X        512    /* EXT    */
  1224. X    };
  1225. X    BufSize = min(512, (speeds[ospeed] * max(LI / 24, 1)));
  1226. X    stdout = fd_open("/dev/tty", F_WRITE|F_LOCKED, 1, ttbuf, BufSize);
  1227. X}
  1228. X
  1229. @//E*O*F fp.c//
  1230. if test 5151 -ne "`wc -c <'fp.c'`"; then
  1231.     echo shar: error transmitting "'fp.c'" '(should have been 5151 characters)'
  1232. fi
  1233. fi # end of overwriting check
  1234. echo shar: extracting "'funcdefs.c'" '(15977 characters)'
  1235. if test -f 'funcdefs.c' ; then 
  1236.   echo shar: will not over-write existing file "'funcdefs.c'"
  1237. else
  1238. sed 's/^X//' >funcdefs.c <<'@//E*O*F funcdefs.c//'
  1239. X/************************************************************************
  1240. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  1241. X * provided to you without charge, and with no warranty.  You may give  *
  1242. X * away copies of JOVE, including sources, provided that this notice is *
  1243. X * included in all the files.                                           *
  1244. X ************************************************************************/
  1245. X
  1246. X#include "jove.h"
  1247. X
  1248. X#ifndef TXT_TO_C
  1249. Xextern int
  1250. X    EscPrefix(),
  1251. X    CtlxPrefix(),
  1252. X    MiscPrefix(),
  1253. X    UnbindC(),
  1254. X    ShowVersion(),
  1255. X    WVisSpace(),
  1256. X#ifdef ANSICODES
  1257. X    AnsiCodes(),
  1258. X#endif
  1259. X    AppReg(),
  1260. X    Apropos(),
  1261. X    BackChar(),
  1262. X    BList(),
  1263. X    FList(),
  1264. X    BUpList(),
  1265. X    FDownList(),
  1266. X    BSexpr(),
  1267. X    BackWord(),
  1268. X    Bof(),
  1269. X    Bol(),
  1270. X    Bos(),
  1271. X    Bow(),
  1272. X    BindAKey(),
  1273. X    BindMac(),
  1274. X    BufPos(),
  1275. X    CasRegLower(),
  1276. X    CasRegUpper(),
  1277. X    CapChar(),
  1278. X    CapWord(),
  1279. X    LowWord(),
  1280. X    UppWord(),
  1281. X#ifdef CHDIR
  1282. X    Chdir(),
  1283. X    prCWD(),
  1284. X    prDIRS(),
  1285. X    Pushd(),
  1286. X    Popd(),
  1287. X#endif
  1288. X    prCTIME(),
  1289. X    ChrToOct(),
  1290. X    ClAndRedraw(),
  1291. X    MakeErrors(),
  1292. X    CopyRegion(),
  1293. X    BufSelect(),
  1294. X    DelBlnkLines(),
  1295. X    DelNChar(),
  1296. X    DelNWord(),
  1297. X    OneWindow(),
  1298. X    DelPChar(),
  1299. X    DelPWord(),
  1300. X    DelReg(),
  1301. X    KillSome(),
  1302. X    DelWtSpace(),
  1303. X    DelCurWindow(),
  1304. X    KeyDesc(),
  1305. X    Digit(),
  1306. X    Digit0(),
  1307. X    Digit1(),
  1308. X    Digit2(),
  1309. X    Digit3(),
  1310. X    Digit4(),
  1311. X    Digit5(),
  1312. X    Digit6(),
  1313. X    Digit7(),
  1314. X    Digit8(),
  1315. X    Digit9(),
  1316. X    DescBindings(),
  1317. X    DescCom(),
  1318. X    Eof(),
  1319. X    Eol(),
  1320. X    Eos(),
  1321. X    Eow(),
  1322. X    ForPara(),
  1323. X    BackPara(),
  1324. X    BufErase(),
  1325. X    PtToMark(),
  1326. X    Extend(),
  1327. X    ExecMacro(),
  1328. X    RunMacro(),
  1329. X    Leave(),
  1330. X    FindFile(),
  1331. X    WindFind(),
  1332. X    FindTag(),
  1333. X    FDotTag(),
  1334. X    ToIndent(),
  1335. X    ForChar(),
  1336. X    FSexpr(),
  1337. X    ForWord(),
  1338. X    FourTime(),
  1339. X    GoLine(),
  1340. X    GrowWindow(),
  1341. X    IncFSearch(),
  1342. X    IncRSearch(),
  1343. X    InsFile(),
  1344. X    Justify(),
  1345. X    RegJustify(),
  1346. X    SetLMargin(),
  1347. X    SetRMargin(),
  1348. X    BufKill(),
  1349. X    KillBos(),
  1350. X    KillEos(),
  1351. X    KillEOL(),
  1352. X    KillExpr(),
  1353. X    BufList(),
  1354. X    NotModified(),
  1355. X    NameMac(),
  1356. X    DelMacro(),
  1357. X    Newline(),
  1358. X    OpenLine(),
  1359. X    LineAI(),
  1360. X    ShowErr(),
  1361. X    NextError(),
  1362. X    PrevError(),
  1363. X    NextLine(),
  1364. X    NextPage(),
  1365. X    NextWindow(),
  1366. X    Recur(),
  1367. X    PopMark(),
  1368. X    PageNWind(),
  1369. X    Tab(),
  1370. X    DoParen(),
  1371. X    ParseAll(),
  1372. X    XParse(),
  1373. X#ifdef SPELL
  1374. X    SpelWords(),
  1375. X#endif
  1376. X#ifdef JOB_CONTROL
  1377. X    PauseJove(),
  1378. X#endif
  1379. X    PrevLine(),
  1380. X    PrevPage(),
  1381. X    PrevWindow(),
  1382. X    Push(),
  1383. X    RegReplace(),
  1384. X    QRepSearch(),
  1385. X    QuotChar(),
  1386. X    ReadFile(),
  1387. X    ReadMacs(),
  1388. X    RedrawDisplay(),
  1389. X    ReNamBuf(),
  1390. X    RepSearch(),
  1391. X    DownScroll(),
  1392. X    UpScroll(),
  1393. X    ForSearch(),
  1394. X    FSrchND(),
  1395. X    RevSearch(),
  1396. X    RSrchND(),
  1397. X    SelfInsert(),
  1398. X    SetVar(),
  1399. X     SetMark(),
  1400. X    ShellCom(),
  1401. X    ShToBuf(),
  1402. X    ShrWindow(),
  1403. X    Source(),
  1404. X#ifdef SPELL
  1405. X    SpelBuffer(),
  1406. X#endif
  1407. X    SplitWind(),
  1408. X    Remember(),
  1409. X    Forget(),
  1410. X    StrLength(),
  1411. X    TransChar(),
  1412. X    TransLines(),
  1413. X    SaveFile(),
  1414. X    WtModBuf(),
  1415. X    WriteFile(),
  1416. X    WriteMacs(),
  1417. X    WrtReg(),
  1418. X    Yank(),
  1419. X    YankPop(),
  1420. X    PrVar(),
  1421. X    FilterRegion(),
  1422. X    WNumLines(),
  1423. X
  1424. X#ifdef IPROCS
  1425. X    ShellProc(),
  1426. X    ProcInt(),
  1427. X    ProcQuit(),
  1428. X    ProcKill(),
  1429. X#  ifndef PIPEPROCS
  1430. X    ProcEof(),
  1431. X    ProcStop(),
  1432. X    ProcCont(),
  1433. X    ProcDStop(),
  1434. X#  endif
  1435. X    ProcSendData(),
  1436. X    ProcNewline(),
  1437. X    ProcList(),
  1438. X    ProcBind(),
  1439. X    Iprocess(),
  1440. X#endif
  1441. X
  1442. X#ifdef LISP
  1443. X    GSexpr(),    /* Grind S Expression. */
  1444. X    AddSpecial(),    /* add lisp special form */
  1445. X#endif
  1446. X    CAutoExec(),
  1447. X    MAutoExec(),
  1448. X
  1449. X    DefMAbbrev(),
  1450. X    DefGAbbrev(),
  1451. X    SaveAbbrevs(),
  1452. X    RestAbbrevs(),
  1453. X    EditAbbrevs(),
  1454. X    BindMtoW(),
  1455. X
  1456. X#ifdef CMT_FMT
  1457. X    Comment(),
  1458. X#endif
  1459. X
  1460. X    MacInter();        /* This is the last one. */
  1461. X
  1462. X
  1463. X#    define WIRED_CMD(c)    c
  1464. X
  1465. X#else TXT_TO_C
  1466. X
  1467. X#    define WIRED_CMD(c)    0
  1468. X
  1469. X#endif TXT_TO_C
  1470. X
  1471. Xstruct cmd    commands[] = {
  1472. X#ifdef LISP
  1473. X    FUNCTION, "add-lisp-special", WIRED_CMD(AddSpecial),
  1474. X#endif
  1475. X#ifdef ANSICODES
  1476. X    FUNCTION, "ansi-codes", WIRED_CMD(AnsiCodes),
  1477. X#endif
  1478. X    FUNCTION, "append-region", WIRED_CMD(AppReg),
  1479. X    FUNCTION, "apropos", WIRED_CMD(Apropos),
  1480. X    FUNCTION, "auto-execute-command", WIRED_CMD(CAutoExec),
  1481. X    FUNCTION, "auto-execute-macro", WIRED_CMD(MAutoExec),
  1482. X    DefMinor(Fill), "auto-fill-mode", 0,
  1483. X    DefMinor(Indent), "auto-indent-mode", 0,
  1484. X    FUNCTION, "backward-character", WIRED_CMD(BackChar),
  1485. X    FUNCTION, "backward-list", WIRED_CMD(BList),
  1486. X    FUNCTION, "backward-paragraph", WIRED_CMD(BackPara),
  1487. X    FUNCTION, "backward-s-expression", WIRED_CMD(BSexpr),
  1488. X    FUNCTION, "backward-sentence", WIRED_CMD(Bos),
  1489. X    FUNCTION, "backward-up-list", WIRED_CMD(BUpList),
  1490. X    FUNCTION, "backward-word", WIRED_CMD(BackWord),
  1491. X    FUNCTION, "beginning-of-file", WIRED_CMD(Bof),
  1492. X    FUNCTION, "beginning-of-line", WIRED_CMD(Bol),
  1493. X    FUNCTION, "beginning-of-window", WIRED_CMD(Bow),
  1494. X    FUNCTION, "bind-to-key", WIRED_CMD(BindAKey),
  1495. X    FUNCTION, "bind-macro-to-key", WIRED_CMD(BindMac),
  1496. X#ifdef ABBREV
  1497. X    FUNCTION, "bind-macro-to-word-abbrev", WIRED_CMD(BindMtoW),
  1498. X#endif
  1499. X    FUNCTION, "buffer-position", WIRED_CMD(BufPos),
  1500. X    DefMajor(CMODE), "c-mode", 0,
  1501. X    FUNCTION, "case-character-capitalize", WIRED_CMD(CapChar),
  1502. X    FUNCTION, "case-region-lower", WIRED_CMD(CasRegLower),
  1503. X    FUNCTION, "case-region-upper", WIRED_CMD(CasRegUpper),
  1504. X    FUNCTION, "case-word-capitalize", WIRED_CMD(CapWord),
  1505. X    FUNCTION, "case-word-lower", WIRED_CMD(LowWord),
  1506. X    FUNCTION, "case-word-upper", WIRED_CMD(UppWord),
  1507. X    FUNCTION, "character-to-octal-insert", WIRED_CMD(ChrToOct),
  1508. X#ifdef CHDIR
  1509. X    FUNCTION, "cd", WIRED_CMD(Chdir),
  1510. X#endif
  1511. X    FUNCTION, "clear-and-redraw", WIRED_CMD(ClAndRedraw),
  1512. X    FUNCTION, "compile-it", WIRED_CMD(MakeErrors),
  1513. X#ifdef IPROCS
  1514. X#  ifndef PIPEPROCS
  1515. X#    ifdef TIOCSLTC
  1516. X    FUNCTION, "continue-process", WIRED_CMD(ProcCont),
  1517. X#    endif
  1518. X#  endif
  1519. X#endif
  1520. X    FUNCTION, "copy-region", WIRED_CMD(CopyRegion),
  1521. X    FUNCTION, "current-error", WIRED_CMD(ShowErr),
  1522. X    FUNCTION, "date", WIRED_CMD(prCTIME),
  1523. X#ifdef ABBREV
  1524. X    FUNCTION, "define-mode-word-abbrev", WIRED_CMD(DefMAbbrev),
  1525. X    FUNCTION, "define-global-word-abbrev", WIRED_CMD(DefGAbbrev),
  1526. X#endif
  1527. X    FUNCTION, "delete-blank-lines", WIRED_CMD(DelBlnkLines),
  1528. X    FUNCTION, "delete-buffer", WIRED_CMD(BufKill),
  1529. X    FUNCTION, "delete-macro", WIRED_CMD(DelMacro),
  1530. X    FUNCTION, "delete-next-character", WIRED_CMD(DelNChar),
  1531. X    FUNCTION, "delete-other-windows", WIRED_CMD(OneWindow),
  1532. X    FUNCTION, "delete-previous-character", WIRED_CMD(DelPChar),
  1533. X    FUNCTION, "delete-white-space", WIRED_CMD(DelWtSpace),
  1534. X    FUNCTION, "delete-current-window", WIRED_CMD(DelCurWindow),
  1535. X    FUNCTION, "describe-bindings", WIRED_CMD(DescBindings),
  1536. X    FUNCTION, "describe-command", WIRED_CMD(DescCom),
  1537. X    FUNCTION, "describe-key", WIRED_CMD(KeyDesc),
  1538. X    FUNCTION, "describe-variable", WIRED_CMD(DescCom),
  1539. X    FUNCTION, "digit", WIRED_CMD(Digit),
  1540. X    FUNCTION, "digit-1", WIRED_CMD(Digit1),
  1541. X    FUNCTION, "digit-2", WIRED_CMD(Digit2),
  1542. X    FUNCTION, "digit-3", WIRED_CMD(Digit3),
  1543. X    FUNCTION, "digit-4", WIRED_CMD(Digit4),
  1544. X    FUNCTION, "digit-5", WIRED_CMD(Digit5),
  1545. X    FUNCTION, "digit-6", WIRED_CMD(Digit6),
  1546. X    FUNCTION, "digit-7", WIRED_CMD(Digit7),
  1547. X    FUNCTION, "digit-8", WIRED_CMD(Digit8),
  1548. X    FUNCTION, "digit-9", WIRED_CMD(Digit9),
  1549. X    FUNCTION, "digit-0", WIRED_CMD(Digit0),
  1550. X#ifdef CHDIR
  1551. X    FUNCTION, "dirs", WIRED_CMD(prDIRS),
  1552. X#endif
  1553. X    FUNCTION, "down-list", WIRED_CMD(FDownList),
  1554. X#ifdef IPROCS
  1555. X#  ifndef PIPEPROCS
  1556. X#    ifdef TIOCSLTC
  1557. X    FUNCTION, "dstop-process", WIRED_CMD(ProcDStop),
  1558. X#    endif
  1559. X#  endif
  1560. X#endif
  1561. X#ifdef ABBREV
  1562. X    FUNCTION, "edit-word-abbrevs", WIRED_CMD(EditAbbrevs),
  1563. X#endif
  1564. X    FUNCTION, "end-of-file", WIRED_CMD(Eof),
  1565. X    FUNCTION, "end-of-line", WIRED_CMD(Eol),
  1566. X    FUNCTION, "end-of-window", WIRED_CMD(Eow),
  1567. X#ifdef IPROCS
  1568. X#  ifndef PIPEPROCS
  1569. X    FUNCTION, "eof-process", WIRED_CMD(ProcEof),
  1570. X#  endif
  1571. X#endif
  1572. X    FUNCTION, "erase-buffer", WIRED_CMD(BufErase),
  1573. X    FUNCTION, "exchange-point-and-mark", WIRED_CMD(PtToMark),
  1574. X    FUNCTION, "execute-named-command", WIRED_CMD(Extend),
  1575. X    FUNCTION, "execute-keyboard-macro", WIRED_CMD(ExecMacro),
  1576. X    FUNCTION, "execute-macro", WIRED_CMD(RunMacro),
  1577. X    FUNCTION, "exit-jove", WIRED_CMD(Leave),
  1578. X#ifdef CMT_FMT
  1579. X     FUNCTION, "fill-comment", WIRED_CMD(Comment),
  1580. X#endif CMT_FMT
  1581. X    FUNCTION, "fill-paragraph", WIRED_CMD(Justify),
  1582. X    FUNCTION, "fill-region", WIRED_CMD(RegJustify),
  1583. X    FUNCTION, "filter-region", WIRED_CMD(FilterRegion),
  1584. X    FUNCTION, "find-file", WIRED_CMD(FindFile),
  1585. X    FUNCTION, "find-tag", WIRED_CMD(FindTag),
  1586. X    FUNCTION, "find-tag-at-point", WIRED_CMD(FDotTag),
  1587. X    FUNCTION, "first-non-blank", WIRED_CMD(ToIndent),
  1588. X    FUNCTION, "forward-character", WIRED_CMD(ForChar),
  1589. X    FUNCTION, "forward-list", WIRED_CMD(FList),
  1590. X    FUNCTION, "forward-paragraph", WIRED_CMD(ForPara),
  1591. X    FUNCTION, "forward-s-expression", WIRED_CMD(FSexpr),
  1592. X    FUNCTION, "forward-sentence", WIRED_CMD(Eos),
  1593. X    FUNCTION, "forward-word", WIRED_CMD(ForWord),
  1594. X    DefMajor(FUNDAMENTAL), "fundamental-mode", 0,
  1595. X#ifdef LISP
  1596. X    FUNCTION, "grind-s-expr", WIRED_CMD(GSexpr),
  1597. X#endif
  1598. X    FUNCTION, "goto-line", WIRED_CMD(GoLine),
  1599. X    FUNCTION, "grow-window", WIRED_CMD(GrowWindow),
  1600. X    FUNCTION, "handle-tab", WIRED_CMD(Tab),
  1601. X    FUNCTION, "i-search-forward", WIRED_CMD(IncFSearch),
  1602. X    FUNCTION, "i-search-reverse", WIRED_CMD(IncRSearch),
  1603. X    FUNCTION, "insert-file", WIRED_CMD(InsFile),
  1604. X#ifdef IPROCS
  1605. X    FUNCTION, "interrupt-process", WIRED_CMD(ProcInt),
  1606. X    FUNCTION, "i-shell-command", WIRED_CMD(Iprocess),
  1607. X#endif
  1608. X    FUNCTION, "kill-next-word", WIRED_CMD(DelNWord),
  1609. X    FUNCTION, "kill-previous-word", WIRED_CMD(DelPWord),
  1610. X#ifdef IPROCS
  1611. X    FUNCTION, "kill-process", WIRED_CMD(ProcKill),
  1612. X#endif
  1613. X    FUNCTION, "kill-region", WIRED_CMD(DelReg),
  1614. X    FUNCTION, "kill-s-expression", WIRED_CMD(KillExpr),
  1615. X    FUNCTION, "kill-some-buffers", WIRED_CMD(KillSome),
  1616. X    FUNCTION, "kill-to-beginning-of-sentence", WIRED_CMD(KillBos),
  1617. X    FUNCTION, "kill-to-end-of-line", WIRED_CMD(KillEOL),
  1618. X    FUNCTION, "kill-to-end-of-sentence", WIRED_CMD(KillEos),
  1619. X    FUNCTION, "left-margin-here", WIRED_CMD(SetLMargin),
  1620. X#ifdef LISP
  1621. X    DefMajor(LISPMODE), "lisp-mode", 0,
  1622. X#endif
  1623. X    FUNCTION, "list-buffers", WIRED_CMD(BufList),
  1624. X#ifdef IPROCS
  1625. X    FUNCTION, "list-processes", WIRED_CMD(ProcList),
  1626. X#endif
  1627. X    FUNCTION, "make-buffer-unmodified", WIRED_CMD(NotModified),
  1628. X    FUNCTION, "make-macro-interactive", WIRED_CMD(MacInter),
  1629. X    FUNCTION, "name-keyboard-macro", WIRED_CMD(NameMac),
  1630. X    FUNCTION, "newline", WIRED_CMD(Newline),
  1631. X    FUNCTION, "newline-and-backup", WIRED_CMD(OpenLine),
  1632. X    FUNCTION, "newline-and-indent", WIRED_CMD(LineAI),
  1633. X    FUNCTION, "next-error", WIRED_CMD(NextError),
  1634. X    FUNCTION, "next-line", WIRED_CMD(NextLine),
  1635. X    FUNCTION, "next-page", WIRED_CMD(NextPage),
  1636. X    FUNCTION, "next-window", WIRED_CMD(NextWindow),
  1637. X    FUNCTION, "number-lines-in-window", WIRED_CMD(WNumLines),
  1638. X    DefMinor(OverWrite), "over-write-mode", 0,
  1639. X    FUNCTION, "page-next-window", WIRED_CMD(PageNWind),
  1640. X    FUNCTION, "paren-flash", WIRED_CMD(DoParen),
  1641. X    FUNCTION, "parse-errors", WIRED_CMD(ParseAll),
  1642. X    FUNCTION, "parse-special-errors", WIRED_CMD(XParse),
  1643. X#ifdef SPELL
  1644. X    FUNCTION, "parse-spelling-errors-in-buffer", WIRED_CMD(SpelWords),
  1645. X#endif
  1646. X#ifdef JOB_CONTROL
  1647. X    FUNCTION, "pause-jove", WIRED_CMD(PauseJove),
  1648. X#else
  1649. X    FUNCTION, "pause-jove", WIRED_CMD(Push),
  1650. X#endif
  1651. X    FUNCTION, "pop-mark", WIRED_CMD(PopMark),
  1652. X#ifdef CHDIR
  1653. X    FUNCTION, "popd", WIRED_CMD(Popd),
  1654. X#endif
  1655. X    FUNCTION, "prefix-1", WIRED_CMD(EscPrefix),
  1656. X    FUNCTION, "prefix-2", WIRED_CMD(CtlxPrefix),
  1657. X    FUNCTION, "prefix-3", WIRED_CMD(MiscPrefix),
  1658. X    FUNCTION, "previous-error", WIRED_CMD(PrevError),
  1659. X    FUNCTION, "previous-line", WIRED_CMD(PrevLine),
  1660. X    FUNCTION, "previous-page", WIRED_CMD(PrevPage),
  1661. X    FUNCTION, "previous-window", WIRED_CMD(PrevWindow),
  1662. X    FUNCTION, "print", WIRED_CMD(PrVar),
  1663. X#ifdef IPROCS
  1664. X    FUNCTION, "process-bind-to-key", WIRED_CMD(ProcBind),
  1665. X    FUNCTION, "process-newline", WIRED_CMD(ProcNewline),
  1666. X    FUNCTION, "process-send-data-no-return", WIRED_CMD(ProcSendData),
  1667. X#endif
  1668. X    FUNCTION, "push-shell", WIRED_CMD(Push),
  1669. X#ifdef CHDIR
  1670. X    FUNCTION, "pushd", WIRED_CMD(Pushd),
  1671. X    FUNCTION, "pwd", WIRED_CMD(prCWD),
  1672. X#endif
  1673. X    FUNCTION, "quadruple-numeric-argument", WIRED_CMD(FourTime),
  1674. X    FUNCTION, "query-replace-string", WIRED_CMD(QRepSearch),
  1675. X#ifdef IPROCS
  1676. X    FUNCTION, "quit-process", WIRED_CMD(ProcQuit),
  1677. X#endif
  1678. X    FUNCTION, "quoted-insert", WIRED_CMD(QuotChar),
  1679. X#ifdef ABBREV
  1680. X    FUNCTION, "read-word-abbrev-file", WIRED_CMD(RestAbbrevs),
  1681. X#endif
  1682. X    FUNCTION, "read-macros-from-file", WIRED_CMD(ReadMacs),
  1683. X    FUNCTION, "redraw-display", WIRED_CMD(RedrawDisplay),
  1684. X    FUNCTION, "recursive-edit", WIRED_CMD(Recur),
  1685. X    FUNCTION, "rename-buffer", WIRED_CMD(ReNamBuf),
  1686. X    FUNCTION, "replace-in-region", WIRED_CMD(RegReplace),
  1687. X    FUNCTION, "replace-string", WIRED_CMD(RepSearch),
  1688. X    FUNCTION, "right-margin-here", WIRED_CMD(SetRMargin),
  1689. X    FUNCTION, "save-file", WIRED_CMD(SaveFile),
  1690. X    FUNCTION, "scroll-down", WIRED_CMD(DownScroll),
  1691. X    FUNCTION, "scroll-up", WIRED_CMD(UpScroll),
  1692. X    FUNCTION, "search-forward", WIRED_CMD(ForSearch),
  1693. X    FUNCTION, "search-forward-nd", WIRED_CMD(FSrchND),
  1694. X    FUNCTION, "search-reverse", WIRED_CMD(RevSearch),
  1695. X    FUNCTION, "search-reverse-nd", WIRED_CMD(RSrchND),
  1696. X    FUNCTION, "select-buffer", WIRED_CMD(BufSelect),
  1697. X    FUNCTION, "self-insert", WIRED_CMD(SelfInsert),
  1698. X    FUNCTION, "set", WIRED_CMD(SetVar),
  1699. X    FUNCTION, "set-mark", WIRED_CMD(SetMark),
  1700. X#ifdef IPROCS    /* for GNU compatibility */
  1701. X    FUNCTION, "shell", WIRED_CMD(ShellProc),
  1702. X#endif
  1703. X    FUNCTION, "shell-command", WIRED_CMD(ShellCom),
  1704. X    FUNCTION, "shell-command-to-buffer", WIRED_CMD(ShToBuf),
  1705. X    DefMinor(ShowMatch), "show-match-mode", 0,
  1706. X    FUNCTION, "shrink-window", WIRED_CMD(ShrWindow),
  1707. X    FUNCTION, "source", WIRED_CMD(Source),
  1708. X#ifdef SPELL
  1709. X    FUNCTION, "spell-buffer", WIRED_CMD(SpelBuffer),
  1710. X#endif
  1711. X    FUNCTION, "split-current-window", WIRED_CMD(SplitWind),
  1712. X    FUNCTION, "start-remembering", WIRED_CMD(Remember),
  1713. X#ifdef IPROCS
  1714. X#  ifndef PIPEPROCS
  1715. X    FUNCTION, "stop-process", WIRED_CMD(ProcStop),
  1716. X#  endif
  1717. X#endif
  1718. X    FUNCTION, "stop-remembering", WIRED_CMD(Forget),
  1719. X    FUNCTION, "string-length", WIRED_CMD(StrLength),
  1720. X#ifdef JOB_CONTROL
  1721. X    FUNCTION, "suspend-jove", WIRED_CMD(PauseJove),
  1722. X#endif
  1723. X    DefMajor(TEXT), "text-mode", 0,
  1724. X    FUNCTION, "transpose-characters", WIRED_CMD(TransChar),
  1725. X    FUNCTION, "transpose-lines", WIRED_CMD(TransLines),
  1726. X    FUNCTION, "unbind-key", WIRED_CMD(UnbindC),
  1727. X    FUNCTION, "version", WIRED_CMD(ShowVersion),
  1728. X    FUNCTION, "visible-spaces-in-window", WIRED_CMD(WVisSpace),
  1729. X    FUNCTION, "visit-file", WIRED_CMD(ReadFile),
  1730. X    FUNCTION, "window-find", WIRED_CMD(WindFind),
  1731. X#ifdef ABBREV
  1732. X    DefMinor(Abbrev), "word-abbrev-mode", 0,
  1733. X    FUNCTION, "write-word-abbrev-file", WIRED_CMD(SaveAbbrevs),
  1734. X#endif
  1735. X    FUNCTION, "write-file", WIRED_CMD(WriteFile),
  1736. X    FUNCTION, "write-macros-to-file", WIRED_CMD(WriteMacs),
  1737. X    FUNCTION, "write-modified-files", WIRED_CMD(WtModBuf),
  1738. X    FUNCTION, "write-region", WIRED_CMD(WrtReg),
  1739. X    FUNCTION, "yank", WIRED_CMD(Yank),
  1740. X    FUNCTION, "yank-pop", WIRED_CMD(YankPop),
  1741. X    FUNCTION, 0, 0
  1742. X};
  1743. X
  1744. X#ifndef TXT_TO_C
  1745. Xdata_obj *
  1746. Xfindcom(prompt)
  1747. Xchar    *prompt;
  1748. X{
  1749. X    /* This is for faster startup.  This just reads until a space or a
  1750. X       tab or a newline character is reached, and then does a
  1751. X       semi-hashed lookup on that string.  This should be much faster
  1752. X       than initializing the minibuffer for each line. */
  1753. X    if (InJoverc) {
  1754. X        char    cmdbuf[128];
  1755. X        register struct cmd    *cmd;
  1756. X        register char    *cp = cmdbuf;
  1757. X        register int    c;
  1758. X        struct cmd    *which;
  1759. X        int    cmdlen,
  1760. X            found = 0;
  1761. X        static struct cmd    *cmdhash[1 + 26];
  1762. X        static int    beenhere = NO;
  1763. X
  1764. X/* special case for prefix commands--only upper case ones */
  1765. X#define hash(c)    ((c == 'P') ? 0 : 1 + (c - 'a'))
  1766. X
  1767. X        /* initialize the hash table */
  1768. X        if (beenhere == NO) {
  1769. X            int    lastc = 0;
  1770. X
  1771. X            for (cmd = commands; cmd->Name != 0; cmd++)
  1772. X                if (lastc != cmd->Name[0]) {
  1773. X                    lastc = cmd->Name[0];
  1774. X                    cmdhash[hash(lastc)] = cmd;
  1775. X                }
  1776. X            beenhere = YES;
  1777. X        }
  1778. X
  1779. X        /* gather the cmd name */
  1780. X        while (((c = getch()) != EOF) && !index(" \t\r\n", c))
  1781. X            *cp++ = c;
  1782. X        if (c == EOF)
  1783. X            return 0;
  1784. X        *cp = '\0';
  1785. X        cmdlen = cp - cmdbuf;
  1786. X        if (cmdlen == 0)
  1787. X            return 0;
  1788. X
  1789. X        /* look it up (in the reduced search space) */
  1790. X        for (cmd = cmdhash[hash(cmdbuf[0])]; cmd->Name[0] == cmdbuf[0]; cmd++) {
  1791. X            if (strncmp(cmd->Name, cmdbuf, cmdlen) == 0) {
  1792. X                if (strcmp(cmd->Name, cmdbuf) == 0)
  1793. X                    return (data_obj *) cmd;
  1794. X                found++;
  1795. X                which = cmd;
  1796. X            }
  1797. X        }
  1798. X        if (found > 1)
  1799. X            complain("[\"%s\" ambiguous]", cmdbuf);
  1800. X        else if (found == 0)
  1801. X            complain("[\"%s\" unknown]", cmdbuf);
  1802. X        else
  1803. X            return (data_obj *) which;
  1804. X    } else {
  1805. X        static char    *strings[(sizeof commands) / sizeof (commands[0])];
  1806. X        static int    beenhere = 0;
  1807. X        register int    com;
  1808. X
  1809. X        if (beenhere == 0) {
  1810. X            register char    **strs = strings;
  1811. X            register struct cmd    *c = commands;
  1812. X
  1813. X            beenhere = 1;
  1814. X            for (; c->Name; c++)
  1815. X                *strs++ = c->Name;
  1816. X            *strs = 0;
  1817. X        }
  1818. X
  1819. X        if ((com = complete(strings, prompt, CASEIND)) < 0)
  1820. X            return 0;
  1821. X        return (data_obj *) &commands[com];
  1822. X    }
  1823. X    /* NOTREACHED */
  1824. X}
  1825. X#endif
  1826. @//E*O*F funcdefs.c//
  1827. if test 15977 -ne "`wc -c <'funcdefs.c'`"; then
  1828.     echo shar: error transmitting "'funcdefs.c'" '(should have been 15977 characters)'
  1829. fi
  1830. fi # end of overwriting check
  1831. echo shar: extracting "'insert.c'" '(13582 characters)'
  1832. if test -f 'insert.c' ; then 
  1833.   echo shar: will not over-write existing file "'insert.c'"
  1834. else
  1835. sed 's/^X//' >insert.c <<'@//E*O*F insert.c//'
  1836. X/************************************************************************
  1837. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  1838. X * provided to you without charge, and with no warranty.  You may give  *
  1839. X * away copies of JOVE, including sources, provided that this notice is *
  1840. X * included in all the files.                                           *
  1841. X ************************************************************************/
  1842. X
  1843. X#include "jove.h"
  1844. X#include "ctype.h"
  1845. X#include "table.h"
  1846. X
  1847. X/* Make a newline after AFTER in buffer BUF, UNLESS after is 0,
  1848. X   in which case we insert the newline before after. */
  1849. X
  1850. XLine *
  1851. Xlistput(buf, after)
  1852. Xregister Buffer    *buf;
  1853. Xregister Line    *after;
  1854. X{
  1855. X    register Line    *newline = nbufline();
  1856. X
  1857. X    if (after == 0) {    /* Before the first line */
  1858. X        newline->l_next = buf->b_first;
  1859. X        newline->l_prev = 0;
  1860. X        buf->b_first = newline;
  1861. X    } else {
  1862. X        newline->l_prev = after;
  1863. X        newline->l_next = after->l_next;
  1864. X        after->l_next = newline;
  1865. X    }
  1866. X    if (newline->l_next)
  1867. X        newline->l_next->l_prev = newline;
  1868. X    else
  1869. X        if (buf)
  1870. X            buf->b_last = newline;
  1871. X    if (buf && buf->b_dot == 0)
  1872. X        buf->b_dot = newline;
  1873. X    return newline;
  1874. X}    
  1875. X
  1876. X/* Divide the current line and move the current line to the next one */
  1877. X
  1878. XLineInsert(num)
  1879. Xregister int    num;
  1880. X{
  1881. X    char    newline[LBSIZE];
  1882. X    register Line    *newdot,
  1883. X            *olddot;
  1884. X    int    oldchar;
  1885. X
  1886. X    olddot = curline;
  1887. X    oldchar = curchar;
  1888. X
  1889. X    newdot = curline;
  1890. X    while (--num >= 0) {
  1891. X        newdot = listput(curbuf, newdot);
  1892. X        SavLine(newdot, NullStr);
  1893. X    }
  1894. X
  1895. X    modify();
  1896. X    if (curchar != 0) {
  1897. X        strcpy(newline, &linebuf[curchar]);
  1898. X        linebuf[curchar] = '\0';    /* Shorten this line */
  1899. X        SavLine(curline, linebuf);
  1900. X        strcpy(linebuf, newline);
  1901. X    } else {    /* Redisplay optimization */
  1902. X        newdot->l_dline = curline->l_dline;
  1903. X        SavLine(curline, NullStr);
  1904. X    }
  1905. X
  1906. X    makedirty(curline);
  1907. X    curline = newdot;
  1908. X    curchar = 0;
  1909. X    makedirty(curline);
  1910. X    IFixMarks(olddot, oldchar, curline, curchar);
  1911. X}    
  1912. X
  1913. X/* Makes the indent of the current line == goal.  If the current indent
  1914. X   is greater than GOAL it deletes.  If more indent is needed, it uses
  1915. X   tabs and spaces to get to where it's going. */
  1916. X
  1917. Xn_indent(goal)
  1918. Xregister int    goal;
  1919. X{
  1920. X    int    dotcol,
  1921. X        incrmt;
  1922. X
  1923. X    ToIndent();
  1924. X    dotcol = calc_pos(linebuf, curchar);
  1925. X    if (goal < dotcol) {
  1926. X        DelWtSpace();
  1927. X        dotcol = 0;
  1928. X    }
  1929. X
  1930. X    for (;;) {
  1931. X        incrmt = (tabstop - (dotcol % tabstop));
  1932. X        if (dotcol + incrmt > goal)
  1933. X            break;
  1934. X        Insert('\t');
  1935. X        dotcol += incrmt;
  1936. X    }
  1937. X    if (dotcol != goal)
  1938. X        DoTimes(Insert(' '), (goal - dotcol));
  1939. X    exp_p = NO;
  1940. X    exp = 1;
  1941. X}
  1942. X
  1943. XSelfInsert()
  1944. X{
  1945. X#ifdef ABBREV
  1946. X    if (MinorMode(Abbrev) && !ismword(LastKeyStruck) &&
  1947. X        !bolp() && ismword(linebuf[curchar - 1]))
  1948. X        AbbrevExpand();
  1949. X#endif
  1950. X    if (MinorMode(OverWrite)) {
  1951. X        register int    num,
  1952. X                i;
  1953. X
  1954. X        for (i = 0, num = exp, exp = 1; i < num; i++) {
  1955. X            int    pos = calc_pos(linebuf, curchar);
  1956. X
  1957. X            if (!eolp()) {
  1958. X                if (linebuf[curchar] == '\t') {
  1959. X                    if ((pos + 1) == ((pos + tabstop) - (pos % tabstop)))
  1960. X                        DelNChar();
  1961. X                } else
  1962. X                    DelNChar();
  1963. X            }
  1964. X            Insert(LastKeyStruck);
  1965. X        }
  1966. X    } else
  1967. X        Insert(LastKeyStruck);
  1968. X
  1969. X    if (MinorMode(Fill) && (curchar >= RMargin ||
  1970. X                   (calc_pos(linebuf, curchar) >= RMargin)))
  1971. X        DoJustify(curline, 0, curline,
  1972. X              curchar + strlen(&linebuf[curchar]), 1, LMargin);
  1973. X}
  1974. X
  1975. XInsert(c)
  1976. X{
  1977. X    if (exp <= 0)
  1978. X        return;
  1979. X    modify();
  1980. X    makedirty(curline);
  1981. X    ins_c(c, linebuf, curchar, exp, LBSIZE);
  1982. X    IFixMarks(curline, curchar, curline, curchar + exp);
  1983. X    curchar += exp;
  1984. X}    
  1985. X
  1986. X/* Tab in to the right place for C mode */
  1987. X
  1988. XTab()
  1989. X{
  1990. X#ifdef LISP
  1991. X    if (MajorMode(LISPMODE)) {
  1992. X        int    dotchar = curchar;
  1993. X        Mark    *m = 0;
  1994. X
  1995. X        ToIndent();
  1996. X        if (dotchar > curchar)
  1997. X            m = MakeMark(curline, dotchar, FLOATER);
  1998. X        (void) lisp_indent();
  1999. X        if (m) {
  2000. X            ToMark(m);
  2001. X            DelMark(m);
  2002. X        } else
  2003. X            ToIndent();
  2004. X        return;
  2005. X    }
  2006. X#endif
  2007. X    if (MajorMode(CMODE) && strlen(linebuf) == 0)
  2008. X        (void) c_indent(CIndIncrmt);
  2009. X    else
  2010. X        SelfInsert();
  2011. X}
  2012. X
  2013. XQuotChar()
  2014. X{
  2015. X    int    c;
  2016. X    extern int    alarmed;    /* If waitfor had to wait. */
  2017. X
  2018. X    c = waitchar();
  2019. X    if (alarmed)
  2020. X        message(key_strokes);
  2021. X    if (c == CTL(J))
  2022. X        LineInsert(exp);
  2023. X    else if (c != CTL(@))
  2024. X        Insert(c);
  2025. X}
  2026. X
  2027. X/* Insert the paren.  If in C mode and c is a '}' then insert the
  2028. X   '}' in the "right" place for C indentation; that is indented 
  2029. X   the same amount as the matching '{' is indented. */
  2030. X
  2031. Xint    PDelay = 5,    /* 1/2 a second */
  2032. X    CIndIncrmt = 8;
  2033. X
  2034. XDoParen()
  2035. X{
  2036. X    Bufpos    *bp = (Bufpos *) -1;
  2037. X    int    nx,
  2038. X        c = LastKeyStruck;
  2039. X
  2040. X    if (!isclosep(c)) {
  2041. X        SelfInsert();
  2042. X        return;
  2043. X    }
  2044. X
  2045. X    if (MajorMode(CMODE) && c == '}' && blnkp(linebuf))
  2046. X        bp = c_indent(0);
  2047. X#ifdef LISP
  2048. X    if (MajorMode(LISPMODE) && c == ')' && blnkp(linebuf))
  2049. X        bp = lisp_indent();
  2050. X#endif
  2051. X    SelfInsert();
  2052. X    if (MinorMode(ShowMatch) && !charp() && !in_macro()) {
  2053. X        BackChar();    /* Back onto the ')' */
  2054. X        if ((int) bp == -1)
  2055. X            bp = m_paren(c, BACKWARD, NO, YES);
  2056. X        ForChar();
  2057. X        if (bp != 0) {
  2058. X            nx = in_window(curwind, bp->p_line);
  2059. X            if (nx != -1) {        /* is visible */
  2060. X                Bufpos    b;
  2061. X
  2062. X                DOTsave(&b);
  2063. X                SetDot(bp);
  2064. X                SitFor(PDelay);
  2065. X                SetDot(&b);
  2066. X            } else
  2067. X                s_mess("%s", lcontents(bp->p_line));
  2068. X        }
  2069. X        mp_error();    /* display error message */
  2070. X    }
  2071. X}
  2072. X
  2073. XLineAI()
  2074. X{
  2075. X    DoNewline(TRUE);
  2076. X}
  2077. X
  2078. XNewline()
  2079. X{
  2080. X    DoNewline(MinorMode(Indent));
  2081. X}    
  2082. X
  2083. XDoNewline(indentp)
  2084. X{
  2085. X    Bufpos    save;
  2086. X    int    indent;
  2087. X
  2088. X    /* first we calculate the indent of the current line */
  2089. X    DOTsave(&save);
  2090. X    ToIndent();
  2091. X    indent = calc_pos(linebuf, curchar);
  2092. X    SetDot(&save);
  2093. X
  2094. X#ifdef ABBREV
  2095. X    if (MinorMode(Abbrev) && !ismword(LastKeyStruck) &&
  2096. X        !bolp() && ismword(linebuf[curchar - 1]))
  2097. X        AbbrevExpand();
  2098. X#endif
  2099. X#ifdef LISP
  2100. X    if (MajorMode(LISPMODE))
  2101. X        DelWtSpace();
  2102. X#endif
  2103. X    else if (blnkp(linebuf))
  2104. X        DelWtSpace();
  2105. X        
  2106. X    /* If there is more than 2 blank lines in a row then don't make
  2107. X       a newline, just move down one. */
  2108. X    if (exp == 1 && eolp() && TwoBlank())
  2109. X        SetLine(curline->l_next);
  2110. X    else
  2111. X        LineInsert(exp);
  2112. X
  2113. X    if (indentp)
  2114. X#ifdef LISP
  2115. X        if (MajorMode(LISPMODE))
  2116. X        (void) lisp_indent();
  2117. X        else
  2118. X#endif
  2119. X        n_indent((LMargin == 0) ? indent : LMargin);
  2120. X}
  2121. X
  2122. Xins_str(str, ok_nl)
  2123. Xregister char    *str;
  2124. X{
  2125. X    register char    c;
  2126. X    Bufpos    save;
  2127. X    int    llen;
  2128. X
  2129. X    if (*str == 0)
  2130. X        return;    /* ain't nothing to insert! */
  2131. X    DOTsave(&save);
  2132. X    llen = strlen(linebuf);
  2133. X    while (c = *str++) {
  2134. X        if (c == '\n' || (ok_nl && llen >= LBSIZE - 2)) {
  2135. X            IFixMarks(save.p_line, save.p_char, curline, curchar);
  2136. X            modify();
  2137. X            makedirty(curline);
  2138. X            LineInsert(1);
  2139. X            DOTsave(&save);
  2140. X            llen = strlen(linebuf);
  2141. X        }
  2142. X        if (c != '\n') {
  2143. X            ins_c(c, linebuf, curchar++, 1, LBSIZE);
  2144. X            llen++;
  2145. X        }
  2146. X    }
  2147. X    IFixMarks(save.p_line, save.p_char, curline, curchar);
  2148. X    modify();
  2149. X    makedirty(curline);
  2150. X}
  2151. X
  2152. XOpenLine()
  2153. X{
  2154. X    Bufpos    dot;
  2155. X
  2156. X    DOTsave(&dot);
  2157. X    LineInsert(exp);    /* Open the lines... */
  2158. X    SetDot(&dot);
  2159. X}
  2160. X
  2161. X/* Take the region FLINE/FCHAR to TLINE/TCHAR and insert it at
  2162. X   ATLINE/ATCHAR in WHATBUF. */
  2163. X
  2164. XBufpos *
  2165. XDoYank(fline, fchar, tline, tchar, atline, atchar, whatbuf)
  2166. XLine    *fline,
  2167. X    *tline,
  2168. X    *atline;
  2169. XBuffer    *whatbuf;
  2170. X{
  2171. X    register Line    *newline;
  2172. X    static Bufpos    bp;
  2173. X    char    save[LBSIZE],
  2174. X        buf[LBSIZE];
  2175. X    Line    *startline = atline;
  2176. X    int    startchar = atchar;
  2177. X
  2178. X    lsave();
  2179. X    if (whatbuf)
  2180. X        modify();
  2181. X    (void) ltobuf(atline, genbuf);
  2182. X    strcpy(save, &genbuf[atchar]);
  2183. X
  2184. X    (void) ltobuf(fline, buf);
  2185. X    if (fline == tline)
  2186. X        buf[tchar] = '\0';
  2187. X
  2188. X    linecopy(genbuf, atchar, &buf[fchar]);
  2189. X    atline->l_dline = putline(genbuf);
  2190. X    makedirty(atline);
  2191. X
  2192. X    fline = fline->l_next;
  2193. X    while (fline != tline->l_next) {
  2194. X        newline = listput(whatbuf, atline);
  2195. X        newline->l_dline = fline->l_dline;
  2196. X        makedirty(newline);
  2197. X        fline = fline->l_next;
  2198. X        atline = newline;
  2199. X        atchar = 0;
  2200. X    }
  2201. X
  2202. X    getline(atline->l_dline, genbuf);
  2203. X    atchar += tchar;
  2204. X    linecopy(genbuf, atchar, save);
  2205. X    atline->l_dline = putline(genbuf);
  2206. X    makedirty(atline);
  2207. X    IFixMarks(startline, startchar, atline, atchar);
  2208. X    bp.p_line = atline;
  2209. X    bp.p_char = atchar;
  2210. X    this_cmd = YANKCMD;
  2211. X    getDOT();            /* Whatever used to be in linebuf */
  2212. X    return &bp;
  2213. X}
  2214. X
  2215. XYankPop()
  2216. X{
  2217. X    Line    *line,
  2218. X        *last;
  2219. X    Mark    *mp = CurMark();
  2220. X    Bufpos    *dot;
  2221. X    int    dir = -1;    /* Direction to rotate the ring */
  2222. X
  2223. X    if (last_cmd != YANKCMD)
  2224. X        complain("Yank something first!");
  2225. X
  2226. X    lfreelist(reg_delete(mp->m_line, mp->m_char, curline, curchar));
  2227. X
  2228. X    /* Now must find a recently killed region. */
  2229. X
  2230. X    if (exp < 0)
  2231. X        dir = 1;
  2232. X
  2233. X    killptr += dir;
  2234. X    for (;;) {
  2235. X        if (killptr < 0)
  2236. X            killptr = NUMKILLS - 1;
  2237. X        else if (killptr >= NUMKILLS)
  2238. X            killptr = 0;
  2239. X        if (killbuf[killptr])
  2240. X            break;
  2241. X        killptr += dir;
  2242. X    }
  2243. X
  2244. X    this_cmd = YANKCMD;
  2245. X
  2246. X    line = killbuf[killptr];
  2247. X    last = lastline(line);
  2248. X    dot = DoYank(line, 0, last, length(last), curline, curchar, curbuf);
  2249. X    MarkSet(CurMark(), curline, curchar);
  2250. X    SetDot(dot);
  2251. X}
  2252. X
  2253. X/* This is an attempt to reduce the amount of memory taken up by each line.
  2254. X   Without this each malloc of a line uses sizeof (line) + sizeof(HEADER)
  2255. X   where line is 3 words and HEADER is 1 word.
  2256. X   This is going to allocate memory in chucks of CHUNKSIZE * sizeof (line)
  2257. X   and divide each chuck into lineS.  A line is free in a chunk when its
  2258. X   line->l_dline == 0, so freeline sets dline to 0. */
  2259. X
  2260. X#define CHUNKSIZE    300
  2261. X
  2262. Xstruct chunk {
  2263. X    int    c_nlines;    /* Number of lines in this chunk (so they
  2264. X                   don't all have to be CHUNKSIZE long). */
  2265. X    Line    *c_block;    /* Chunk of memory */
  2266. X    struct chunk    *c_nextfree;    /* Next chunk of lines */
  2267. X};
  2268. X
  2269. Xstatic struct chunk    *fchunk = 0;
  2270. Xstatic Line    *ffline = 0;    /* First free line */
  2271. X
  2272. Xfreeline(line)
  2273. Xregister Line    *line;
  2274. X{
  2275. X    line->l_dline = 0;
  2276. X    line->l_next = ffline;
  2277. X    if (ffline)
  2278. X        ffline->l_prev = line;
  2279. X    line->l_prev = 0;
  2280. X    ffline = line;
  2281. X}
  2282. X
  2283. Xlfreelist(first)
  2284. Xregister Line    *first;
  2285. X{
  2286. X    if (first)
  2287. X        lfreereg(first, lastline(first));
  2288. X}
  2289. X
  2290. X/* Append region from line1 to line2 onto the free list of lines */
  2291. X
  2292. Xlfreereg(line1, line2)
  2293. Xregister Line    *line1,
  2294. X        *line2;
  2295. X{
  2296. X    register Line    *next,
  2297. X            *last = line2->l_next;
  2298. X
  2299. X    while (line1 != last) {
  2300. X        next = line1->l_next;
  2301. X        freeline(line1);
  2302. X        line1 = next;
  2303. X    }
  2304. X}
  2305. X
  2306. Xstatic
  2307. Xnewchunk()
  2308. X{
  2309. X    register Line    *newline;
  2310. X    register int    i;
  2311. X    struct chunk    *f;
  2312. X    int    nlines = CHUNKSIZE;
  2313. X
  2314. X    f = (struct chunk *) emalloc(sizeof (struct chunk));
  2315. X    if (f == 0)
  2316. X        return 0;
  2317. X
  2318. X    if ((f->c_block = (Line *) malloc((unsigned) (sizeof (Line) * nlines))) == 0) {
  2319. X        while (nlines > 0) {
  2320. X            f->c_block = (Line *) malloc((unsigned) (sizeof (Line) * nlines));
  2321. X            if (f->c_block != 0)
  2322. X                break;
  2323. X            nlines /= 2;
  2324. X        }
  2325. X    }
  2326. X
  2327. X    if (nlines <= 0)
  2328. X        return 0;
  2329. X
  2330. X    f->c_nlines = nlines;
  2331. X    for (i = 0, newline = f->c_block; i < nlines; newline++, i++)
  2332. X        freeline(newline);
  2333. X    f->c_nextfree = fchunk;
  2334. X    fchunk = f;
  2335. X    return 1;
  2336. X}
  2337. X
  2338. X/* New BUFfer LINE */
  2339. X
  2340. XLine *
  2341. Xnbufline()
  2342. X{
  2343. X    register Line    *newline;
  2344. X
  2345. X    if (ffline == 0)    /* No free list */
  2346. X        if (newchunk() == 0)
  2347. X            complain("[Out of lines] ");
  2348. X    newline = ffline;
  2349. X    ffline = ffline->l_next;
  2350. X    if (ffline)
  2351. X        ffline->l_prev = 0;
  2352. X    return newline;
  2353. X}
  2354. X
  2355. X/* Remove the free lines, in chunk c, from the free list because they are
  2356. X   no longer free. */
  2357. X
  2358. Xstatic
  2359. Xremfreelines(c)
  2360. Xregister struct chunk    *c;
  2361. X{
  2362. X    register Line    *lp;
  2363. X    register int    i;
  2364. X
  2365. X    for (lp = c->c_block, i = 0; i < c->c_nlines; i++, lp++) {
  2366. X        if (lp->l_prev)
  2367. X            lp->l_prev->l_next = lp->l_next;
  2368. X        else
  2369. X            ffline = lp->l_next;
  2370. X        if (lp->l_next)
  2371. X            lp->l_next->l_prev = lp->l_prev;
  2372. X    }
  2373. X}
  2374. X
  2375. X/* This is used to garbage collect the chunks of lines when malloc fails
  2376. X   and we are NOT looking for a new buffer line.  This goes through each
  2377. X   chunk, and if every line in a given chunk is not allocated, the entire
  2378. X   chunk is `free'd by "free()". */
  2379. X
  2380. XGCchunks()
  2381. X{
  2382. X    register struct chunk    *cp;
  2383. X    struct chunk    *prev = 0,
  2384. X            *next = 0;
  2385. X    register int    i;
  2386. X    register Line    *newline;
  2387. X
  2388. X     for (cp = fchunk; cp != 0; cp = next) {
  2389. X        for (i = 0, newline = cp->c_block; i < cp->c_nlines; newline++, i++)
  2390. X            if (newline->l_dline != 0)
  2391. X                break;
  2392. X
  2393. X         next = cp->c_nextfree;
  2394. X
  2395. X        if (i == cp->c_nlines) {        /* Unlink it!!! */
  2396. X            if (prev)
  2397. X                prev->c_nextfree = cp->c_nextfree;
  2398. X            else
  2399. X                fchunk = cp->c_nextfree;
  2400. X            remfreelines(cp);
  2401. X            free((char *) cp->c_block);
  2402. X            free((char *) cp);
  2403. X        } else
  2404. X            prev = cp;
  2405. X    }
  2406. X}
  2407. X
  2408. X#ifdef LISP
  2409. X
  2410. X/* Grind S-Expr */
  2411. X
  2412. XGSexpr()
  2413. X{
  2414. X    Bufpos    dot,
  2415. X        end;
  2416. X
  2417. X    if (linebuf[curchar] != '(')
  2418. X        complain((char *) 0);
  2419. X    DOTsave(&dot);
  2420. X    FSexpr();
  2421. X    DOTsave(&end);
  2422. X    exp = 1;
  2423. X    SetDot(&dot);
  2424. X    for (;;) {
  2425. X        if (curline == end.p_line)
  2426. X            break;
  2427. X        line_move(FORWARD, NO);
  2428. X        if (!blnkp(linebuf))
  2429. X            (void) lisp_indent();
  2430. X    }
  2431. X    SetDot(&dot);
  2432. X}
  2433. X
  2434. X/* lisp_indent() indents a new line in Lisp Mode, according to where
  2435. X   the matching close-paren would go if we typed that (sort of). */
  2436. X
  2437. Xprivate Table    *specials = NIL;
  2438. X
  2439. Xprivate
  2440. Xinit_specials()
  2441. X{
  2442. X    static char *words[] = {
  2443. X        "case",
  2444. X        "def",
  2445. X        "dolist",
  2446. X        "fluid-let",
  2447. X        "lambda",
  2448. X        "let",
  2449. X        "lexpr",
  2450. X        "macro",
  2451. X        "named-l",    /* named-let and named-lambda */
  2452. X        "nlambda",
  2453. X        "prog",
  2454. X        "selectq",
  2455. X        0
  2456. X    };
  2457. X    char    **wordp = words;
  2458. X
  2459. X    specials = make_table();
  2460. X    while (*wordp)
  2461. X        add_word(*wordp++, specials);
  2462. X}
  2463. X
  2464. XAddSpecial()
  2465. X{
  2466. X    char    *word;
  2467. X
  2468. X    word = ask((char *) 0, ProcFmt);
  2469. X    if (specials == NIL)
  2470. X        init_specials();
  2471. X    add_word(copystr(word), specials);
  2472. X}
  2473. X
  2474. XBufpos *
  2475. Xlisp_indent()
  2476. X{
  2477. X    Bufpos    *bp,
  2478. X        savedot;
  2479. X    int    goal;
  2480. X
  2481. X    bp = m_paren(')', BACKWARD, NO, YES);
  2482. X
  2483. X    if (bp == 0)
  2484. X        return 0;
  2485. X
  2486. X    /* We want to end up
  2487. X     
  2488. X         (atom atom atom ...
  2489. X               ^ here.
  2490. X     */
  2491. X
  2492. X    DOTsave(&savedot);
  2493. X    SetDot(bp);
  2494. X    DoTimes(ForChar(), 1);
  2495. X    if (linebuf[curchar] != '(') {
  2496. X        register Word    *wp;
  2497. X
  2498. X        if (specials == NIL)
  2499. X            init_specials();
  2500. X        for (wp = table_top(specials); wp != NIL; wp = next_word(wp))
  2501. X            if (casencmp(word_text(wp), &linebuf[curchar], word_length(wp)) == 0)
  2502. X                break;
  2503. X        if (wp == NIL) {    /* not special */
  2504. X            int    c_char = curchar;
  2505. X
  2506. X            WITH_TABLE(curbuf->b_major)
  2507. X                ForWord();
  2508. X            END_TABLE();
  2509. X            if (LookingAt("[ \t]*;\\|[ \t]*$", linebuf, curchar))
  2510. X                curchar = c_char;
  2511. X            else while (linebuf[curchar] == ' ')
  2512. X                curchar++;
  2513. X        } else
  2514. X            curchar++;
  2515. X    }
  2516. X    goal = calc_pos(linebuf, curchar);
  2517. X    SetDot(&savedot);
  2518. X    n_indent(goal);
  2519. X
  2520. X    return bp;
  2521. X}
  2522. X#endif LISP
  2523. @//E*O*F insert.c//
  2524. if test 13582 -ne "`wc -c <'insert.c'`"; then
  2525.     echo shar: error transmitting "'insert.c'" '(should have been 13582 characters)'
  2526. fi
  2527. fi # end of overwriting check
  2528. echo shar: extracting "'table.c'" '(1122 characters)'
  2529. if test -f 'table.c' ; then 
  2530.   echo shar: will not over-write existing file "'table.c'"
  2531. else
  2532. sed 's/^X//' >table.c <<'@//E*O*F table.c//'
  2533. X/************************************************************************
  2534. X * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  2535. X * provided to you without charge, and with no warranty.  You may give  *
  2536. X * away copies of JOVE, including sources, provided that this notice is *
  2537. X * included in all the files.                                           *
  2538. X ************************************************************************/
  2539. X
  2540. X#include "jove.h"
  2541. X#include "table.h"
  2542. X
  2543. Xprivate Table    *tables = NIL;
  2544. X
  2545. XTable *
  2546. Xmake_table()
  2547. X{
  2548. X    Table    *tab = (Table *) emalloc(sizeof *tab);
  2549. X
  2550. X    tab->t_next = tables;
  2551. X    tables = tab;
  2552. X    tab->t_wordlist = NIL;
  2553. X
  2554. X    return tab;
  2555. X}
  2556. X
  2557. XWord *
  2558. Xword_in_table(text, table)
  2559. Xchar    *text;
  2560. XTable    *table;
  2561. X{
  2562. X    register Word    *w;
  2563. X
  2564. X    for (w = table_top(table); w != NIL; w = next_word(w))
  2565. X        if (strcmp(word_text(w), text) == 0)
  2566. X            break;    /* already in list */
  2567. X    return w;
  2568. X}
  2569. X
  2570. Xadd_word(wname, table)
  2571. Xchar    *wname;
  2572. XTable    *table;
  2573. X{
  2574. X    register Word    *w;
  2575. X
  2576. X    if (w = word_in_table(wname, table))
  2577. X        return;
  2578. X    w = (Word *) emalloc(sizeof *w);
  2579. X    word_text(w) = wname;
  2580. X    next_word(w) = table_top(table);
  2581. X    table_top(table) = w;
  2582. X}
  2583. @//E*O*F table.c//
  2584. if test 1122 -ne "`wc -c <'table.c'`"; then
  2585.     echo shar: error transmitting "'table.c'" '(should have been 1122 characters)'
  2586. fi
  2587. fi # end of overwriting check
  2588. echo shar: "End of archive 3 (of 13)."
  2589. cp /dev/null ark3isdone
  2590. DONE=true
  2591. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13; do
  2592.     if test -f ark${I}isdone; then
  2593.         echo "You have run archive ${I}."
  2594.     else
  2595.         echo "You still need to run archive ${I}."
  2596.         DONE=false
  2597.     fi
  2598. done
  2599. case $DONE in
  2600.     true)
  2601.         echo "You have run all 13 archives."
  2602.         echo 'Now read the README and Makefile.'
  2603.         ;;
  2604. esac
  2605. ##  End of shell archive.
  2606. exit 0
  2607.